[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\nexecutors:\n  golang:\n    docker:\n      - image: cimg/go:1.26\n\njobs:\n  lint:\n    executor: golang\n    steps:\n      - checkout\n      # Download and cache dependencies\n      - restore_cache: &restore-cache\n          keys:\n            - go-mod-{{ checksum \"go.sum\" }}\n      - run:\n          name: Install dependencies\n          command: |\n            go mod download\n      - run:\n          name: Go fmt\n          command: |\n            RES=\"$(gofmt -s -l .)\"\n            if [ -n \"${RES}\" ]\n            then\n              echo \"${RES}\"\n              exit 1\n            fi\n      - run:\n          name: GolangCI Lint\n          command: |\n            golangci-lint --version\n            golangci-lint run --verbose\n      - save_cache: &save-cache\n          paths:\n            - /home/circleci/go/pkg/mod\n          key: go-mod-{{ checksum \"go.sum\" }}\n  test:\n    executor: golang\n    steps:\n      - checkout\n      - restore_cache:\n          <<: *restore-cache\n      - run:\n          name: Install dependencies\n          command: |\n            go mod download\n      - run:\n          name: Test\n          command: |\n            make test\n      - save_cache:\n          <<: *save-cache\n\nworkflows:\n  lint_test:\n    jobs:\n      - lint\n      - test:\n          requires:\n            - lint\n"
  },
  {
    "path": ".codacy.yml",
    "content": "---\nexclude_paths:\n  - \"internal/*test.go\"\n"
  },
  {
    "path": ".dockerignore",
    "content": ".circleci\nCLI.md\n.codacy.yml\nCODEOWNERS\ndeploy\n.git\n.gitignore\nLICENSE\nMakefile\nREADME.md\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# sup3rS3cretMes5age Development Instructions\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\n## Working Effectively\n\n### Bootstrap and Dependencies\n- Install Go 1.25.1+: `go version` must show go1.25.1 or later\n- Install Docker: Required for Vault development server\n- Install CLI tools for testing:\n  ```bash\n  # Ubuntu/Debian\n  sudo apt-get update && sudo apt-get install -y curl jq\n  \n  # Check installations\n  go version    # Must be 1.25.1+\n  docker --version\n  curl --version\n  jq --version\n  ```\n\n### Download Dependencies and Build\n- Download Go modules: `go mod download` -- takes 1-2 minutes. NEVER CANCEL. Set timeout to 180+ seconds.\n- Build binary: `go build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go` -- takes <1 second after dependencies downloaded.\n- Install linter: `curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.2` -- takes 30-60 seconds. Current system has v2.7.2.\n\n### Testing and Validation\n- Run tests: `make test` -- takes 2-3 minutes. NEVER CANCEL. Set timeout to 300+ seconds.\n- Run linting: `export PATH=$PATH:$(go env GOPATH)/bin && golangci-lint run --timeout 300s` -- takes 30-45 seconds. NEVER CANCEL. Set timeout to 600+ seconds.\n- Check formatting: `gofmt -s -l .` -- should return no output if properly formatted\n- Run static analysis: `go vet ./...` -- takes <5 seconds\n\n### Running the Application\n**ALWAYS run the bootstrapping steps first before starting the application.**\n\n#### Start Development Vault Server\n```bash\ndocker run -d --name vault-dev -p 8200:8200 -e VAULT_DEV_ROOT_TOKEN_ID=supersecret hashicorp/vault:latest\n```\nWait 3-5 seconds for Vault to start, then verify: `curl -s http://localhost:8200/v1/sys/health`\n\n#### Start the Application\n```bash\nVAULT_ADDR=http://localhost:8200 VAULT_TOKEN=supersecret SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=\":8080\" ./sup3rs3cret\n```\n\nThe application will start on port 8080. Access at http://localhost:8080\n\n#### Cleanup Development Environment\n```bash\ndocker stop vault-dev && docker rm vault-dev\n```\n\n### Docker Build and Deployment\nThe project includes comprehensive Docker support:\n\n#### Local Development with Docker Compose\n```bash\n# Start full stack (Vault + App on port 8082)\nmake run\n# or\ndocker compose -f deploy/docker-compose.yml up --build -d\n\n# View logs\nmake logs\n\n# Stop services\nmake stop\n\n# Clean up\nmake clean\n```\n\nThe default `docker-compose.yml` runs the app on port 8082 (HTTP) with Vault using token `supersecret`.\n\n#### Production Docker Image\n```bash\n# Build multi-platform image with attestations\nmake image\n# Builds for linux/amd64 and linux/arm64 with SBOM and provenance\n\n# Alternative: Build local image only\ndocker compose -f deploy/docker-compose.yml build\n```\n\n**Note**: In some CI/containerized environments, Docker builds may encounter certificate verification issues with Go proxy. If this occurs, use local Go builds instead.\n\n## Validation\n\n### Manual Testing Scenarios\nALWAYS run through these complete end-to-end scenarios after making changes:\n\n#### Test 1: Basic Message Flow\n```bash\n# Create secret message\nTOKEN=$(curl -X POST -s -F 'msg=test secret message' http://localhost:8080/secret | jq -r .token)\n\n# Retrieve message (should work once)\ncurl -s \"http://localhost:8080/secret?token=$TOKEN\" | jq .\n\n# Try to retrieve again (should fail - message self-destructs)\ncurl -s \"http://localhost:8080/secret?token=$TOKEN\" | jq .\n```\n\n#### Test 2: CLI Integration\n```bash\n# Test CLI workflow\necho \"test CLI message\" | curl -sF 'msg=<-' http://localhost:8080/secret | jq -r .token | awk '{print \"http://localhost:8080/getmsg?token=\"$1}'\n```\n\n#### Test 3: Health Check\n```bash\ncurl -s http://localhost:8080/health  # Should return \"OK\"\n```\n\n### Pre-commit Validation\nAlways run these commands before committing:\n- `gofmt -s -l .` -- Should return no output\n- `go vet ./...` -- Should complete without errors  \n- `export PATH=$PATH:$(go env GOPATH)/bin && golangci-lint run --timeout 300s` -- Should complete without errors. NEVER CANCEL. Set timeout to 600+ seconds.\n- `make test` -- Should pass all tests. NEVER CANCEL. Set timeout to 300+ seconds.\n\n## Common Tasks\n\n### Key Application Features\n- **Self-Destructing Messages**: Messages are automatically deleted after first read\n- **Vault Backend**: Uses HashiCorp Vault's cubbyhole for secure temporary storage\n- **TTL Support**: Configurable time-to-live (default 48h, max 168h/7 days)\n- **File Upload**: Support for file uploads with base64 encoding (max 50MB)\n- **One-Time Tokens**: Vault tokens with exactly 2 uses (1 to create, 1 to read)\n- **Rate Limiting**: 10 requests per second to prevent abuse\n- **TLS Support**: Auto TLS via Let's Encrypt or manual certificate configuration\n- **No External Dependencies**: All JavaScript/fonts self-hosted for privacy\n\n### Configuration Environment Variables\n- `VAULT_ADDR`: Vault server address (e.g., `http://localhost:8200`)\n- `VAULT_TOKEN`: Vault authentication token (e.g., `supersecret` for dev)\n- `SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS`: HTTP port (e.g., `:8080`)\n- `SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS`: HTTPS port (e.g., `:443`)\n- `SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED`: Enable HTTP->HTTPS redirect (`true`/`false`)\n- `SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN`: Domain for Let's Encrypt auto-TLS\n- `SUPERSECRETMESSAGE_TLS_CERT_FILEPATH`: Manual TLS certificate path\n- `SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH`: Manual TLS certificate key path\n- `SUPERSECRETMESSAGE_VAULT_PREFIX`: Vault path prefix (default: `cubbyhole/`)\n\n### Repository Structure\n```\n.\n├── cmd/sup3rS3cretMes5age/\n│   └── main.go                     # Application entry point (23 lines)\n├── internal/                       # Core application logic\n│   ├── config.go                   # Configuration handling (77 lines)\n│   ├── handlers.go                 # HTTP request handlers (88 lines)\n│   ├── handlers_test.go            # Handler unit tests (87 lines)\n│   ├── server.go                   # Web server setup (94 lines)\n│   ├── vault.go                    # Vault integration (174 lines)\n│   └── vault_test.go               # Vault unit tests (66 lines)\n├── web/static/                     # Frontend assets (HTML, CSS, JS)\n│   ├── index.html                  # Main page (5KB)\n│   ├── getmsg.html                 # Message retrieval page (7.8KB)\n│   ├── application.css             # Styling (2.3KB)\n│   ├── clipboard-2.0.11.min.js     # Copy functionality (9KB)\n│   ├── montserrat.css              # Font definitions\n│   ├── robots.txt                  # Search engine rules\n│   ├── fonts/                      # Self-hosted Montserrat font files\n│   └── icons/                      # Favicon and app icons\n├── deploy/                         # Docker and deployment configs\n│   ├── Dockerfile                  # Multi-stage container build\n│   ├── docker-compose.yml          # Local development stack (Vault + App)\n│   └── charts/supersecretmessage/  # Helm c(lint + test pipeline)\n.codacy.yml        # Code quality config\n.dockerignore      # Docker ignore patterns\n.git/              # Git repository data\n.github/           # GitHub configuration (copilot-instructions.md)\n.gitignore         # Git ignore patterns\nCLI.md             # Command-line usage guide (313 lines, Bash/Zsh/Fish examples)\nCODEOWNERS         # GitHub code owners\nLICENSE            # MIT license\nMakefile           # Build targets (test, image, build, run, logs, stop, clean)\nMakefile.buildx    # Advanced buildx targets (multi-platform, AWS ECR)\nREADME.md          # Main documentation (176 lines)\ncmd/               # Application entry points\ndeploy/            # Deployment configurations (Docker, Helm)\ngo.mod             # Go module file (go 1.25.1)\ngo.sum             # Go dependency checksums\ninternal/          # Internal packages (609 lines total)\nweb/               # Web assets (static HTML, CSS, JS, fonts, icons)\n### Frequently Used Commands Output\n\n#### Repository Root Files\n```bash\n$ ls -la\n.circleci/         # CircleCI configuration  \n.codacy.yml        # Code quality config\n.dockerignore      # Docker ignore patterns\n.git/              # Git repository data\n.gitignore         # Git ignore patterns\nCLI.md             # Command-line usage guide\nCODEOWNERS         # GitHub code owners\nLICENSE            # MIT license\nMakefile           # Build targets\nREADME.md          # Main documentation\ncmd/               # Application entry points\ndeploy/            # Deployment configurations\ngo.mod             # Go module file\ngo.sum             # Go checksum file\ninternal/          # Internal packages\nweb/               # Web assets\n```\n\n#### Package.json Equivalent (go.mod)\n```go\nmodule github.com/algolia/sup3rS3cretMes5age\n\ngo 1.25.1\n\nrequire (\n    github.com/hashicorp/vault v1.21.0\n    github.com/hashicorp/vault/api v1.22.0\n    github.com/labstack/echo/v4 v4.13.4\n    github.com/stretchr/testify v1.11.1\n    golang.org/x/crypto v0.45.0\n)\n```\n\n### CLI Functions (from CLI.md)\nAdd to your shell profile for convenient CLI usage:\n\n```bash\n# Basic function for Bash/Zsh\no() { \n    local url=\"http://localhost:8080\"\n    local response\n    \n    if [ $# -eq 0 ]; then\n        response=$(curl -sF 'msg=<-' \"$url/secret\")\n    else\n        response=$(cat \"$@\" | curl -sF 'msg=<-' \"$url/secret\")\n    fi\n    \n    if [ $? -eq 0 ]; then\n        echo \"$response\" | jq -r .token | awk -v url=\"$url\" '{print url\"/getmsg?token=\"$1}'\n    else\n        echo \"Error: Failed to create secure message\" >&2\n        return 1\n    fi\n}\n```\n\n### Troubleshooting\n\n**\"go: ... tls: failed to verify certificate\"**\n- This may occur in Docker builds in some CI environments\n- Solution: Use local Go builds instead: `go build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go`\n\n**\"jq: command not found\"**\n```bash\n# Ubuntu/Debian\nsudo apt-get install jq\n\n# macOS  \nbrew install jq\n```\n\n**\"vault connection refused\"**\n- Ensure Vault dev server is running: `docker ps | grep vault`\n- Check Vault health: `curl http://localhost:8200/v1/sys/health`\n- Restart if needed: `docker restart vault-dev`\n\n**Test failures with Vault errors**\n- Tests create their own Vault instances\n- Verbose logging is normal (200+ lines per test)\n- NEVER CANCEL tests - they clean up automatically\n\n**Port 8082 already in use**\n```bash\n# Find what's using the port\nsudo lsof -i :8082\n# or\nsudo netstat -tulpn | grep 8082\n\n# Stop docker-compose if running\nmake stop\n```\n\n**Build fails with \"cannot find package\"**\n```bash\n# Clean Go module cache and re-download\ngo clean -modcache\ngo mod download\n```\n\n### Makefile Targets Reference\n```bash\nmake test          # Run all unit tests (takes 2-3 min)\nmake image         # Build multi-platform Docker image with attestations\nmake build         # Build Docker image via docker-compose\nmake run           # Start docker-compose stack (Vault + App on :8082)\nmake run-local     # Clean and start docker-compose\nmake logs          # Tail docker-compose logs\nmake stop          # Stop docker-compose services\nmake clean         # Remove docker-compose containers\n```\n\n### CircleCI Pipeline\nThe project uses CircleCI with two jobs:\n1. **lint**: Format checking (gofmt), golangci-lint v2.6.0\n2. **test**: Unit tests via `make test`\n\nPipeline runs on Go 1.25 docker image (`cimg/go:1.25`).\n\n### Helm Deployment\nHelm chart located in `deploy/charts/supersecretmessage/`:\n- Chart version: 0.1.0\n- App version: 0.2.5\n- Includes: Deployment, Service, Ingress, HPA, ServiceAccount\n- Configurable: Vault connection, TLS settings, resource limits\n- See [deploy/charts/README.md](deploy/charts/README.md) for details\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".gitignore",
    "content": "bin\nvendor/**/\nnginx/**/\nstatic/.well-known\n*.pem\n*.key\n/sup3rS3cretMes5age\nsup3rs3cret\nsup3rs3cret-*\n.DS_Store\n"
  },
  {
    "path": ".golangci.yml",
    "content": "# Config format version\nversion: 2\n\nrun:\n  concurrency: 1\n  timeout: 8m\n"
  },
  {
    "path": "AWS_DEPLOYMENT.md",
    "content": "# AWS Deployment Guide\n\nThis guide provides step-by-step instructions for deploying sup3rS3cretMes5age on AWS using various services. The application consists of two main components:\n- The sup3rS3cretMes5age web application\n- A HashiCorp Vault server for secure secret storage\n\n## Table of Contents\n\n1. [Prerequisites](#prerequisites)\n2. [Option 1: ECS with Fargate (Recommended)](#option-1-ecs-with-fargate-recommended)\n3. [Option 2: EKS (Kubernetes)](#option-2-eks-kubernetes)\n4. [Option 3: EC2 with Docker](#option-3-ec2-with-docker)\n5. [Security Considerations](#security-considerations)\n6. [Cost Optimization](#cost-optimization)\n7. [Troubleshooting](#troubleshooting)\n\n## Prerequisites\n\nBefore starting, ensure you have:\n\n1. **AWS CLI** installed and configured with appropriate permissions\n2. **Docker** installed for building and testing images locally\n3. **Domain name** (recommended for HTTPS with Let's Encrypt)\n4. **AWS Account** with the following IAM permissions:\n   - ECS full access\n   - ECR full access\n   - Application Load Balancer management\n   - VPC management\n   - IAM role creation\n   - Route 53 (if using custom domain)\n\n## Option 1: ECS with Fargate (Recommended)\n\nThis option uses AWS ECS with Fargate for a serverless container deployment, which is cost-effective and easy to manage.\n\n### Step 1: Set up ECR Repository\n\nFirst, create a private ECR repository to store your Docker images:\n\n```bash\n# Set your AWS region\nexport AWS_REGION=us-east-1\nexport AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)\n\n# Create ECR repositories\naws ecr create-repository \\\n    --repository-name sup3rs3cretmes5age \\\n    --region $AWS_REGION\n\naws ecr create-repository \\\n    --repository-name vault \\\n    --region $AWS_REGION\n\n# Get login token for ECR\naws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com\n```\n\n### Step 2: Build and Push Docker Images\n\nBuild and push the application image to ECR:\n\n```bash\n# Clone and build the application\ngit clone https://github.com/algolia/sup3rS3cretMes5age.git\ncd sup3rS3cretMes5age\n\n# Build the application image (with network=host to handle certificate issues)\ndocker build --network=host -f deploy/Dockerfile -t sup3rs3cretmes5age .\n\n# Tag for ECR\ndocker tag sup3rs3cretmes5age:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/sup3rs3cretmes5age:latest\n\n# Push to ECR\ndocker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/sup3rs3cretmes5age:latest\n\n# Pull and push Vault image to your ECR\ndocker pull hashicorp/vault:latest\ndocker tag hashicorp/vault:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/vault:latest\ndocker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/vault:latest\n```\n\n### Step 3: Create VPC and Security Groups\n\nCreate a VPC with public and private subnets:\n\n```bash\n# Create VPC\nexport VPC_ID=$(aws ec2 create-vpc \\\n    --cidr-block 10.0.0.0/16 \\\n    --query 'Vpc.VpcId' \\\n    --output text)\n\naws ec2 create-tags \\\n    --resources $VPC_ID \\\n    --tags Key=Name,Value=sup3rs3cretmes5age-vpc\n\n# Create Internet Gateway\nexport IGW_ID=$(aws ec2 create-internet-gateway \\\n    --query 'InternetGateway.InternetGatewayId' \\\n    --output text)\n\naws ec2 attach-internet-gateway \\\n    --vpc-id $VPC_ID \\\n    --internet-gateway-id $IGW_ID\n\n# Create public subnets in two AZs\nexport PUBLIC_SUBNET_1=$(aws ec2 create-subnet \\\n    --vpc-id $VPC_ID \\\n    --cidr-block 10.0.1.0/24 \\\n    --availability-zone ${AWS_REGION}a \\\n    --query 'Subnet.SubnetId' \\\n    --output text)\n\nexport PUBLIC_SUBNET_2=$(aws ec2 create-subnet \\\n    --vpc-id $VPC_ID \\\n    --cidr-block 10.0.2.0/24 \\\n    --availability-zone ${AWS_REGION}b \\\n    --query 'Subnet.SubnetId' \\\n    --output text)\n\n# Create private subnets\nexport PRIVATE_SUBNET_1=$(aws ec2 create-subnet \\\n    --vpc-id $VPC_ID \\\n    --cidr-block 10.0.3.0/24 \\\n    --availability-zone ${AWS_REGION}a \\\n    --query 'Subnet.SubnetId' \\\n    --output text)\n\nexport PRIVATE_SUBNET_2=$(aws ec2 create-subnet \\\n    --vpc-id $VPC_ID \\\n    --cidr-block 10.0.4.0/24 \\\n    --availability-zone ${AWS_REGION}b \\\n    --query 'Subnet.SubnetId' \\\n    --output text)\n\n# Create route table for public subnets\nexport PUBLIC_RT=$(aws ec2 create-route-table \\\n    --vpc-id $VPC_ID \\\n    --query 'RouteTable.RouteTableId' \\\n    --output text)\n\naws ec2 create-route \\\n    --route-table-id $PUBLIC_RT \\\n    --destination-cidr-block 0.0.0.0/0 \\\n    --gateway-id $IGW_ID\n\n# Associate public subnets with route table\naws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_1 --route-table-id $PUBLIC_RT\naws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_2 --route-table-id $PUBLIC_RT\n\n# Enable auto-assign public IPs for public subnets\naws ec2 modify-subnet-attribute --subnet-id $PUBLIC_SUBNET_1 --map-public-ip-on-launch\naws ec2 modify-subnet-attribute --subnet-id $PUBLIC_SUBNET_2 --map-public-ip-on-launch\n```\n\nCreate security groups:\n\n```bash\n# Security group for Application Load Balancer\nexport ALB_SG=$(aws ec2 create-security-group \\\n    --group-name sup3rs3cretmes5age-alb-sg \\\n    --description \"Security group for sup3rs3cretmes5age ALB\" \\\n    --vpc-id $VPC_ID \\\n    --query 'GroupId' \\\n    --output text)\n\n# Allow HTTP and HTTPS traffic to ALB\naws ec2 authorize-security-group-ingress \\\n    --group-id $ALB_SG \\\n    --protocol tcp \\\n    --port 80 \\\n    --cidr 0.0.0.0/0\n\naws ec2 authorize-security-group-ingress \\\n    --group-id $ALB_SG \\\n    --protocol tcp \\\n    --port 443 \\\n    --cidr 0.0.0.0/0\n\n# Security group for ECS tasks\nexport ECS_SG=$(aws ec2 create-security-group \\\n    --group-name sup3rs3cretmes5age-ecs-sg \\\n    --description \"Security group for sup3rs3cretmes5age ECS tasks\" \\\n    --vpc-id $VPC_ID \\\n    --query 'GroupId' \\\n    --output text)\n\n# Allow traffic from ALB to ECS tasks\naws ec2 authorize-security-group-ingress \\\n    --group-id $ECS_SG \\\n    --protocol tcp \\\n    --port 80 \\\n    --source-group $ALB_SG\n\n# Allow Vault communication between tasks\naws ec2 authorize-security-group-ingress \\\n    --group-id $ECS_SG \\\n    --protocol tcp \\\n    --port 8200 \\\n    --source-group $ECS_SG\n```\n\n### Step 4: Create Application Load Balancer\n\n```bash\n# Create Application Load Balancer\nexport ALB_ARN=$(aws elbv2 create-load-balancer \\\n    --name sup3rs3cretmes5age-alb \\\n    --subnets $PUBLIC_SUBNET_1 $PUBLIC_SUBNET_2 \\\n    --security-groups $ALB_SG \\\n    --query 'LoadBalancers[0].LoadBalancerArn' \\\n    --output text)\n\n# Get ALB DNS name\nexport ALB_DNS=$(aws elbv2 describe-load-balancers \\\n    --load-balancer-arns $ALB_ARN \\\n    --query 'LoadBalancers[0].DNSName' \\\n    --output text)\n\necho \"ALB DNS Name: $ALB_DNS\"\n\n# Create target group\nexport TARGET_GROUP_ARN=$(aws elbv2 create-target-group \\\n    --name sup3rs3cretmes5age-tg \\\n    --protocol HTTP \\\n    --port 80 \\\n    --vpc-id $VPC_ID \\\n    --target-type ip \\\n    --health-check-path / \\\n    --health-check-interval-seconds 30 \\\n    --health-check-timeout-seconds 5 \\\n    --healthy-threshold-count 2 \\\n    --unhealthy-threshold-count 3 \\\n    --query 'TargetGroups[0].TargetGroupArn' \\\n    --output text)\n\n# Create listener\naws elbv2 create-listener \\\n    --load-balancer-arn $ALB_ARN \\\n    --protocol HTTP \\\n    --port 80 \\\n    --default-actions Type=forward,TargetGroupArn=$TARGET_GROUP_ARN\n```\n\n### Step 5: Set up ECS Cluster and Task Definitions\n\nCreate ECS cluster:\n\n```bash\n# Create ECS cluster\naws ecs create-cluster --cluster-name sup3rs3cretmes5age-cluster\n```\n\nCreate IAM roles for ECS:\n\n```bash\n# Create ECS task execution role\ncat > ecs-task-execution-role-trust-policy.json << EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"ecs-tasks.amazonaws.com\"\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n\naws iam create-role \\\n    --role-name ecsTaskExecutionRole \\\n    --assume-role-policy-document file://ecs-task-execution-role-trust-policy.json\n\naws iam attach-role-policy \\\n    --role-name ecsTaskExecutionRole \\\n    --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy\n\n# Get the role ARN\nexport TASK_EXECUTION_ROLE_ARN=$(aws iam get-role \\\n    --role-name ecsTaskExecutionRole \\\n    --query 'Role.Arn' \\\n    --output text)\n```\n\nCreate task definition:\n\n```bash\ncat > task-definition.json << EOF\n{\n  \"family\": \"sup3rs3cretmes5age\",\n  \"networkMode\": \"awsvpc\",\n  \"requiresCompatibilities\": [\"FARGATE\"],\n  \"cpu\": \"512\",\n  \"memory\": \"1024\",\n  \"executionRoleArn\": \"$TASK_EXECUTION_ROLE_ARN\",\n  \"containerDefinitions\": [\n    {\n      \"name\": \"vault\",\n      \"image\": \"$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/vault:latest\",\n      \"essential\": true,\n      \"environment\": [\n        {\n          \"name\": \"VAULT_DEV_ROOT_TOKEN_ID\",\n          \"value\": \"supersecret\"\n        }\n      ],\n      \"portMappings\": [\n        {\n          \"containerPort\": 8200,\n          \"protocol\": \"tcp\"\n        }\n      ],\n      \"logConfiguration\": {\n        \"logDriver\": \"awslogs\",\n        \"options\": {\n          \"awslogs-group\": \"/ecs/sup3rs3cretmes5age\",\n          \"awslogs-region\": \"$AWS_REGION\",\n          \"awslogs-stream-prefix\": \"vault\"\n        }\n      },\n      \"linuxParameters\": {\n        \"capabilities\": {\n          \"add\": [\"IPC_LOCK\"]\n        }\n      }\n    },\n    {\n      \"name\": \"supersecret\",\n      \"image\": \"$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/sup3rs3cretmes5age:latest\",\n      \"essential\": true,\n      \"dependsOn\": [\n        {\n          \"containerName\": \"vault\",\n          \"condition\": \"START\"\n        }\n      ],\n      \"environment\": [\n        {\n          \"name\": \"VAULT_ADDR\",\n          \"value\": \"http://localhost:8200\"\n        },\n        {\n          \"name\": \"VAULT_TOKEN\",\n          \"value\": \"supersecret\"\n        },\n        {\n          \"name\": \"SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS\",\n          \"value\": \":80\"\n        }\n      ],\n      \"portMappings\": [\n        {\n          \"containerPort\": 80,\n          \"protocol\": \"tcp\"\n        }\n      ],\n      \"logConfiguration\": {\n        \"logDriver\": \"awslogs\",\n        \"options\": {\n          \"awslogs-group\": \"/ecs/sup3rs3cretmes5age\",\n          \"awslogs-region\": \"$AWS_REGION\",\n          \"awslogs-stream-prefix\": \"supersecret\"\n        }\n      }\n    }\n  ]\n}\nEOF\n\n# Create CloudWatch log group\naws logs create-log-group --log-group-name /ecs/sup3rs3cretmes5age\n\n# Register task definition\naws ecs register-task-definition --cli-input-json file://task-definition.json\n```\n\n### Step 6: Create ECS Service\n\n```bash\n# Create ECS service\ncat > service-definition.json << EOF\n{\n  \"serviceName\": \"sup3rs3cretmes5age-service\",\n  \"cluster\": \"sup3rs3cretmes5age-cluster\",\n  \"taskDefinition\": \"sup3rs3cretmes5age\",\n  \"desiredCount\": 1,\n  \"launchType\": \"FARGATE\",\n  \"networkConfiguration\": {\n    \"awsvpcConfiguration\": {\n      \"subnets\": [\"$PRIVATE_SUBNET_1\", \"$PRIVATE_SUBNET_2\"],\n      \"securityGroups\": [\"$ECS_SG\"],\n      \"assignPublicIp\": \"DISABLED\"\n    }\n  },\n  \"loadBalancers\": [\n    {\n      \"targetGroupArn\": \"$TARGET_GROUP_ARN\",\n      \"containerName\": \"supersecret\",\n      \"containerPort\": 80\n    }\n  ]\n}\nEOF\n\naws ecs create-service --cli-input-json file://service-definition.json\n```\n\n### Step 7: Configure Domain and HTTPS (Optional but Recommended)\n\nIf you have a domain name, you can configure HTTPS:\n\n```bash\n# Request SSL certificate (replace with your domain)\nexport DOMAIN_NAME=\"secrets.yourdomain.com\"\n\nexport CERT_ARN=$(aws acm request-certificate \\\n    --domain-name $DOMAIN_NAME \\\n    --validation-method DNS \\\n    --query 'CertificateArn' \\\n    --output text)\n\necho \"Certificate ARN: $CERT_ARN\"\necho \"Complete DNS validation in ACM console, then continue...\"\n\n# After DNS validation is complete, create HTTPS listener\naws elbv2 create-listener \\\n    --load-balancer-arn $ALB_ARN \\\n    --protocol HTTPS \\\n    --port 443 \\\n    --certificates CertificateArn=$CERT_ARN \\\n    --default-actions Type=forward,TargetGroupArn=$TARGET_GROUP_ARN\n\n# Create Route 53 record (if using Route 53)\n# You'll need to create this manually or use your DNS provider\n```\n\n## Option 2: EKS (Kubernetes)\n\nFor teams already using Kubernetes, you can deploy using the provided Helm chart on Amazon EKS.\n\n### Prerequisites for EKS Deployment\n\n```bash\n# Install required tools\n# - kubectl\n# - helm\n# - eksctl (recommended for cluster creation)\n\n# Create EKS cluster\neksctl create cluster \\\n    --name sup3rs3cretmes5age \\\n    --region $AWS_REGION \\\n    --nodegroup-name standard-workers \\\n    --node-type t3.medium \\\n    --nodes 2 \\\n    --nodes-min 1 \\\n    --nodes-max 4 \\\n    --managed\n```\n\n### Deploy with Helm\n\n```bash\n# Add Vault Helm repository\nhelm repo add hashicorp https://helm.releases.hashicorp.com\nhelm repo update\n\n# Install Vault\nhelm install vault hashicorp/vault \\\n    --set \"server.dev.enabled=true\" \\\n    --set \"server.dev.devRootToken=supersecret\"\n\n# Deploy sup3rS3cretMes5age using the provided Helm chart\ncd sup3rS3cretMes5age/deploy/charts/supersecretmessage\n\n# Update values.yaml for your configuration\nhelm install sup3rs3cretmes5age . \\\n    --set image.repository=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/sup3rs3cretmes5age \\\n    --set image.tag=latest \\\n    --set vault.address=http://vault:8200 \\\n    --set vault.token=supersecret\n\n# Create ingress for external access\nkubectl apply -f - << EOF\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: sup3rs3cretmes5age-ingress\n  annotations:\n    kubernetes.io/ingress.class: alb\n    alb.ingress.kubernetes.io/scheme: internet-facing\n    alb.ingress.kubernetes.io/target-type: ip\nspec:\n  rules:\n  - http:\n      paths:\n      - path: /\n        pathType: Prefix\n        backend:\n          service:\n            name: sup3rs3cretmes5age\n            port:\n              number: 80\nEOF\n```\n\n## Option 3: EC2 with Docker\n\nFor a simpler setup, you can deploy on EC2 instances using Docker Compose.\n\n### Step 1: Launch EC2 Instance\n\n```bash\n# Create key pair\naws ec2 create-key-pair \\\n    --key-name sup3rs3cretmes5age-key \\\n    --query 'KeyMaterial' \\\n    --output text > sup3rs3cretmes5age-key.pem\n\nchmod 400 sup3rs3cretmes5age-key.pem\n\n# Launch EC2 instance\nexport INSTANCE_ID=$(aws ec2 run-instances \\\n    --image-id ami-0c55b159cbfafe1d0 \\\n    --count 1 \\\n    --instance-type t3.small \\\n    --key-name sup3rs3cretmes5age-key \\\n    --security-groups default \\\n    --query 'Instances[0].InstanceId' \\\n    --output text)\n\n# Get public IP\nexport INSTANCE_IP=$(aws ec2 describe-instances \\\n    --instance-ids $INSTANCE_ID \\\n    --query 'Reservations[0].Instances[0].PublicIpAddress' \\\n    --output text)\n```\n\n### Step 2: Configure EC2 Instance\n\n```bash\n# SSH to instance and set up Docker\nssh -i sup3rs3cretmes5age-key.pem ec2-user@$INSTANCE_IP\n\n# On the EC2 instance:\nsudo yum update -y\nsudo yum install -y docker\nsudo service docker start\nsudo usermod -a -G docker ec2-user\n\n# Install Docker Compose\nsudo curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose\nsudo chmod +x /usr/local/bin/docker-compose\n\n# Clone repository\ngit clone https://github.com/algolia/sup3rS3cretMes5age.git\ncd sup3rS3cretMes5age\n\n# Start services\ndocker-compose -f deploy/docker-compose.yml up -d\n```\n\n## Security Considerations\n\n### 1. Use AWS Secrets Manager for Vault Token\n\nInstead of hardcoding the Vault token, use AWS Secrets Manager:\n\n```bash\n# Create secret\naws secretsmanager create-secret \\\n    --name sup3rs3cretmes5age/vault-token \\\n    --description \"Vault root token for sup3rs3cretmes5age\" \\\n    --secret-string \"your-secure-vault-token\"\n\n# Update task definition to use secrets\n# Add to containerDefinitions[].secrets:\n{\n  \"name\": \"VAULT_TOKEN\",\n  \"valueFrom\": \"arn:aws:secretsmanager:region:account:secret:sup3rs3cretmes5age/vault-token\"\n}\n```\n\n### 2. Enable VPC Flow Logs\n\n```bash\naws ec2 create-flow-logs \\\n    --resource-type VPC \\\n    --resource-ids $VPC_ID \\\n    --traffic-type ALL \\\n    --log-destination-type cloud-watch-logs \\\n    --log-group-name VPCFlowLogs\n```\n\n### 3. Use HTTPS Only\n\nAlways configure HTTPS and redirect HTTP traffic:\n\n```bash\n# Modify task definition to enable HTTPS redirect\n{\n  \"name\": \"SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED\",\n  \"value\": \"true\"\n}\n```\n\n### 4. Implement Network ACLs\n\nCreate restrictive network ACLs for additional security:\n\n```bash\n# Create network ACL\nexport NACL_ID=$(aws ec2 create-network-acl \\\n    --vpc-id $VPC_ID \\\n    --query 'NetworkAcl.NetworkAclId' \\\n    --output text)\n\n# Add rules as needed for your security requirements\n```\n\n## Cost Optimization\n\n### 1. Use Fargate Spot for Development\n\nFor non-production environments, consider using Fargate Spot:\n\n```bash\n# Update service to use Fargate Spot\naws ecs put-cluster-capacity-providers \\\n    --cluster sup3rs3cretmes5age-cluster \\\n    --capacity-providers FARGATE FARGATE_SPOT\n```\n\n### 2. Auto Scaling\n\nConfigure auto scaling for production workloads:\n\n```bash\n# Register scalable target\naws application-autoscaling register-scalable-target \\\n    --service-namespace ecs \\\n    --scalable-dimension ecs:service:DesiredCount \\\n    --resource-id service/sup3rs3cretmes5age-cluster/sup3rs3cretmes5age-service \\\n    --min-capacity 1 \\\n    --max-capacity 10\n\n# Create scaling policy\naws application-autoscaling put-scaling-policy \\\n    --policy-name sup3rs3cretmes5age-scaling-policy \\\n    --service-namespace ecs \\\n    --scalable-dimension ecs:service:DesiredCount \\\n    --resource-id service/sup3rs3cretmes5age-cluster/sup3rs3cretmes5age-service \\\n    --policy-type TargetTrackingScaling \\\n    --target-tracking-scaling-policy-configuration file://scaling-policy.json\n```\n\n### 3. Use Reserved Instances for EC2\n\nFor long-running deployments, consider Reserved Instances to reduce costs.\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Service won't start**: Check CloudWatch logs for container errors\n2. **Can't access application**: Verify security group rules and target group health\n3. **SSL certificate issues**: Ensure DNS validation is complete\n4. **Vault connection errors**: Check network connectivity between containers\n\n### Debugging Commands\n\n```bash\n# Check ECS service status\naws ecs describe-services \\\n    --cluster sup3rs3cretmes5age-cluster \\\n    --services sup3rs3cretmes5age-service\n\n# View logs\naws logs tail /ecs/sup3rs3cretmes5age --follow\n\n# Check target group health\naws elbv2 describe-target-health \\\n    --target-group-arn $TARGET_GROUP_ARN\n\n# Test internal connectivity\naws ecs execute-command \\\n    --cluster sup3rs3cretmes5age-cluster \\\n    --task <task-id> \\\n    --container supersecret \\\n    --interactive \\\n    --command \"/bin/sh\"\n```\n\n### Support Resources\n\n- [AWS ECS Documentation](https://docs.aws.amazon.com/ecs/)\n- [HashiCorp Vault Documentation](https://www.vaultproject.io/docs)\n- [Application Load Balancer Documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/)\n\n---\n\nThis guide provides multiple deployment options on AWS. Choose the option that best fits your team's expertise and requirements. For production deployments, we recommend Option 1 (ECS with Fargate) for its balance of simplicity, scalability, and cost-effectiveness."
  },
  {
    "path": "CLI.md",
    "content": "# Command Line Interface (CLI) Usage\n\n## Overview\n\nThe sup3rS3cretMes5age CLI integration allows you to quickly create secure, self-destructing message links directly from your terminal. This is particularly useful for:\n\n- **Sharing sensitive configuration files** with team members\n- **Sending API keys or passwords** securely\n- **Sharing command outputs** that contain sensitive information\n- **Quick secure file sharing** without leaving the terminal\n- **Automating secure message creation** in scripts and workflows\n\n## Example Usage\n\n```bash\n# Share a secret file\n$ o secret-config.json\nhttps://your-domain.com/getmsg?token=abc123def456\n\n# Share command output\n$ kubectl get secrets -o yaml | o\nhttps://your-domain.com/getmsg?token=xyz789uvw012\n\n# Share multiple files\n$ o database.env api-keys.txt\nhttps://your-domain.com/getmsg?token=mno345pqr678\n```\n\nThe generated URL can only be accessed **once** and will self-destruct after being viewed, ensuring your sensitive data remains secure.\n\n## Shell Integration\n\n### Prerequisites\n\nBefore using any of the shell functions below, ensure you have:\n- `curl` installed\n- `jq` installed (for JSON parsing)\n- Access to a sup3rS3cretMes5age deployment\n\nReplace `https://your-domain.com` in all examples with your actual sup3rS3cretMes5age deployment URL.\n\n---\n\n### Bash\n\nAdd this function to your `~/.bashrc`:\n\n```bash\no() {\n    if [ $# -eq 0 ]; then\n        # Read from stdin if no arguments\n        curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print \"https://your-domain.com/getmsg?token=\"$1}'\n    else\n        # Read from files\n        cat \"$@\" | curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print \"https://your-domain.com/getmsg?token=\"$1}'\n    fi\n}\n```\n\n**Usage:**\n```bash\n# From file\no secret.txt\n\n# From stdin\necho \"secret message\" | o\n\n# From command output\nps aux | o\n\n# Multiple files\no file1.txt file2.txt\n```\n\n---\n\n### Zsh\n\nAdd this function to your `~/.zshrc`:\n\n```zsh\no() {\n    if [ $# -eq 0 ]; then\n        # Read from stdin if no arguments\n        curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print \"https://your-domain.com/getmsg?token=\"$1}'\n    else\n        # Read from files\n        cat \"$@\" | curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print \"https://your-domain.com/getmsg?token=\"$1}'\n    fi\n}\n```\n\n**Advanced Zsh version with error handling:**\n```zsh\no() {\n    local url=\"https://your-domain.com\"\n    local response\n    \n    if [ $# -eq 0 ]; then\n        response=$(curl -sF 'msg=<-' \"$url/secret\")\n    else\n        response=$(cat \"$@\" | curl -sF 'msg=<-' \"$url/secret\")\n    fi\n    \n    if [ $? -eq 0 ]; then\n        echo \"$response\" | jq -r .token | awk -v url=\"$url\" '{print url\"/getmsg?token=\"$1}'\n    else\n        echo \"Error: Failed to create secure message\" >&2\n        return 1\n    fi\n}\n```\n\n---\n\n### Fish Shell\n\nAdd this function to your `~/.config/fish/config.fish`:\n\n```fish\nfunction o\n    set -l url \"https://your-domain.com\"\n    \n    if test (count $argv) -eq 0\n        # Read from stdin\n        set response (curl -sF 'msg=<-' \"$url/secret\")\n    else\n        # Read from files\n        set response (cat $argv | curl -sF 'msg=<-' \"$url/secret\")\n    end\n    \n    if test $status -eq 0\n        echo $response | jq -r .token | awk -v url=\"$url\" '{print url\"/getmsg?token=\"$1}'\n    else\n        echo \"Error: Failed to create secure message\" >&2\n        return 1\n    end\nend\n```\n\n**Fish-specific features:**\n```fish\n# With Fish's command substitution\nset secret_url (echo \"my secret\" | o)\necho \"Share this URL: $secret_url\"\n\n# Using Fish's pipe to variable\necho \"secret data\" | o | read -g secret_link\n```\n\n---\n\n### Windows Subsystem for Linux (WSL)\n\nFor WSL (Ubuntu/Debian), add this to your `~/.bashrc`:\n\n```bash\no() {\n    local url=\"https://your-domain.com\"\n    local response\n    \n    # Handle Windows line endings\n    if [ $# -eq 0 ]; then\n        response=$(curl -sF 'msg=<-' \"$url/secret\")\n    else\n        response=$(cat \"$@\" | dos2unix | curl -sF 'msg=<-' \"$url/secret\")\n    fi\n    \n    if [ $? -eq 0 ]; then\n        token=$(echo \"$response\" | jq -r .token)\n        echo \"$url/getmsg?token=$token\"\n        \n        # Optional: Copy to Windows clipboard\n        if command -v clip.exe >/dev/null 2>&1; then\n            echo \"$url/getmsg?token=$token\" | clip.exe\n            echo \"(URL copied to Windows clipboard)\"\n        fi\n    else\n        echo \"Error: Failed to create secure message\" >&2\n        return 1\n    fi\n}\n```\n\n**WSL-specific usage:**\n```bash\n# Share a Windows file\no /mnt/c/Users/username/secret.txt\n\n# Copy result to Windows clipboard automatically\necho \"secret\" | o\n```\n\n---\n\n## Advanced Usage\n\n### Environment Configuration\n\nCreate a configuration file `~/.sup3rsecret` to avoid hardcoding URLs:\n\n```bash\n# ~/.sup3rsecret\nSUPERSECRET_URL=\"https://your-domain.com\"\nSUPERSECRET_COPY_TO_CLIPBOARD=true\nSUPERSECRET_SHOW_QR=false\n```\n\nThen modify your shell function to source this config:\n\n```bash\no() {\n    # Load config\n    [ -f ~/.sup3rsecret ] && source ~/.sup3rsecret\n    local url=\"${SUPERSECRET_URL:-https://your-domain.com}\"\n    \n    # ... rest of function\n}\n```\n\n### QR Code Generation\n\nAdd QR code generation for easy mobile sharing:\n\n```bash\no() {\n    # ... existing function logic ...\n    \n    local secret_url=\"$url/getmsg?token=$token\"\n    echo \"$secret_url\"\n    \n    # Generate QR code if requested\n    if [ \"$SUPERSECRET_SHOW_QR\" = \"true\" ] && command -v qrencode >/dev/null 2>&1; then\n        echo \"QR Code:\"\n        qrencode -t ANSIUTF8 \"$secret_url\"\n    fi\n}\n```\n\n### Expiration Time\n\nSome deployments might support custom expiration times:\n\n```bash\no() {\n    local ttl=\"${1:-3600}\"  # Default 1 hour\n    shift\n    \n    if [ $# -eq 0 ]; then\n        response=$(curl -sF 'msg=<-' -F \"ttl=$ttl\" \"$url/secret\")\n    else\n        response=$(cat \"$@\" | curl -sF 'msg=<-' -F \"ttl=$ttl\" \"$url/secret\")\n    fi\n    \n    # ... rest of function\n}\n```\n\n## Security Considerations\n\n1. **HTTPS Only**: Always use HTTPS URLs to prevent interception\n2. **Trusted Networks**: Avoid using on untrusted networks\n3. **Shell History**: Consider using `set +o history` before running sensitive commands\n4. **File Permissions**: Ensure your shell config files have appropriate permissions (`chmod 600 ~/.bashrc`)\n5. **Cleanup**: The message will self-destruct after being read once\n\n## Troubleshooting\n\n### Common Issues\n\n**\"jq: command not found\"**\n```bash\n# Ubuntu/Debian\nsudo apt-get install jq\n\n# macOS\nbrew install jq\n\n# CentOS/RHEL\nsudo yum install jq\n```\n\n**\"curl: command not found\"**\n```bash\n# Ubuntu/Debian\nsudo apt-get install curl\n\n# CentOS/RHEL\nsudo yum install curl\n```\n\n**Function not found after adding to config**\n```bash\n# Reload your shell configuration\nsource ~/.bashrc  # or ~/.zshrc, ~/.config/fish/config.fish\n```\n\n**SSL certificate errors**\n```bash\n# For self-signed certificates (NOT recommended for production)\ncurl -k -sF 'msg=<-' https://your-domain.com/secret\n```\n\n### Testing Your Setup\n\nTest your function with a simple message:\n\n```bash\necho \"test message\" | o\n```\n\nYou should receive a URL that you can open in your browser to verify the message appears and then self-destructs.\n"
  },
  {
    "path": "CODEOWNERS",
    "content": "# Algolia is maintaining this open source repository\n# New additions are welcome and can be submitted to our teams for code reviews and approvals\n\n* @algolia/foundation @algolia/security\n\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Eran Chetzroni @ Algolia\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": "Makefile",
    "content": "# For MacOS use darwin\nTARGET_OS ?= linux\n\n# When developing locally, change this to whatever fqdn you are using for 127.0.0.1\nDOMAIN ?= localhost\n\nCOMPOSE_OPTS := -f deploy/docker-compose.yml\nDOCKER_OPS := -f deploy/Dockerfile\n\nTAG=$(shell git describe --tags --abbrev=0)\nVERSION=$(shell echo \"$(TAG)\" | sed -e 's/^v//')\nCOMMIT=$(shell git rev-parse --short HEAD)\nBUILD_DATE=$(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\")\nVCS_REF=$(shell git rev-parse HEAD)\n\nATTESTATIONS=--provenance=true --sbom=true\nPLATFORMS=--platform linux/amd64,linux/arm64\n\ntest:\n\tgo test ./... -v\n\nimage:\n\tdocker buildx build $(ATTESTATIONS) $(PLATFORMS) \\\n\t\t--build-arg VERSION=$(VERSION) \\\n\t\t--build-arg BUILD_DATE=\"$(BUILD_DATE)\" \\\n\t\t--build-arg VCS_REF=$(VCS_REF) \\\n\t\t-t algolia/supersecretmessage:$(VERSION) \\\n\t\t-t algolia/supersecretmessage:$(COMMIT) \\\n\t\t-t algolia/supersecretmessage:latest \\\n\t\t$(DOCKER_OPS) .\n\nbuild:\n\t@docker compose $(COMPOSE_OPTS) build\n\nclean:\n\t@docker compose $(COMPOSE_OPTS) rm -fv\n\nrun-local: clean\n        @DOMAIN=$(DOMAIN) \\\n\tdocker compose $(COMPOSE_OPTS) up --build -d\n\nrun:\n\t@DOMAIN=$(DOMAIN) \\\n        docker compose $(COMPOSE_OPTS) up --build -d\n\nlogs:\n\t@docker compose $(COMPOSE_OPTS) logs -f\n\nstop:\n\t@docker compose $(COMPOSE_OPTS) stop\n\n.PHONY: test image build clean run-local run logs stop\n"
  },
  {
    "path": "README.md",
    "content": "# sup3rS3cretMes5age\n\n[![Go Version](https://img.shields.io/github/go-mod/go-version/algolia/sup3rS3cretMes5age.svg)](https://golang.org/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![CircleCI](https://img.shields.io/circleci/build/github/algolia/sup3rS3cretMes5age/master)](https://circleci.com/gh/algolia/sup3rS3cretMes5age)\n[![Go Report Card](https://goreportcard.com/badge/github.com/algolia/sup3rS3cretMes5age)](https://goreportcard.com/report/github.com/algolia/sup3rS3cretMes5age)  \n\n[![Awesome F/OSS](https://awsmfoss.com/content/images/2024/02/awsm-foss-badge.600x128.rounded.png)](https://awsmfoss.com/sup3rs3cretmes5age)\n\nA simple, secure, **self-destructing message service** that uses HashiCorp Vault as a backend for temporary secret storage. Share sensitive information with confidence knowing it will be automatically deleted after being read once.\n\n![self-destruct](https://media.giphy.com/media/LBlyAAFJ71eMw/giphy.gif)\n\n> 🔐 **Security First**: Messages are stored in Vault's cubbyhole backend with one-time tokens and automatic expiration.\n\nRead more about the reasoning behind this project in the [relevant blog post](https://blog.algolia.com/secure-tool-for-one-time-self-destructing-messages/).\n\n## ✨ Features\n\n- **🔥 Self-Destructing Messages**: Messages are automatically deleted after first read\n- **⏰ Configurable TTL**: Set custom expiration times (default 48h, max 7 days)\n- **📎 File Upload Support**: Share files up to 50MB with base64 encoding\n- **🔐 Vault-Backed Security**: Uses HashiCorp Vault's cubbyhole for tamper-proof storage\n- **🎫 One-Time Tokens**: Vault tokens with exactly 2 uses (create + retrieve)\n- **🚦 Rate Limiting**: Built-in protection (10 requests/second)\n- **🔒 TLS/HTTPS Support**: \n  - Automatic TLS via [Let's Encrypt](https://letsencrypt.org/)\n  - Manual certificate configuration\n  - HTTP to HTTPS redirection\n- **🌐 No External Dependencies**: All assets self-hosted for privacy\n- **📦 Lightweight**: Only 8.9KB JavaScript (no jQuery)\n- **🐳 Docker Ready**: Multi-platform images (amd64, arm64) with SBOM\n- **☸️ Kubernetes Support**: Helm chart included\n- **🖥️ CLI Integration**: Shell functions for Bash, Zsh, and Fish\n\n## 📋 Table of Contents\n\n- [Features](#-features)\n- [Frontend Dependencies](#frontend-dependencies)\n- [Quick Start](#-quick-start)\n- [Deployment](#deployment)\n- [Configuration](#configuration-options)\n- [Command Line Usage](#command-line-usage)\n- [Helm Chart](#helm)\n- [API Reference](#-api-reference)\n- [Development](#-development)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Frontend Dependencies\n\nThe web interface is built with modern **vanilla JavaScript** and has minimal external dependencies:\n\n| Dependency | Size | Purpose |\n|------------|------|----------|\n| ClipboardJS v2.0.11 | 8.9KB | Copy to clipboard functionality |\n| Montserrat Font | 46KB | Self-hosted typography |\n| Custom CSS | 2.3KB | Application styling |\n\n✅ **No external CDNs or tracking** - All dependencies are self-hosted for privacy and security.\n\n📦 **Total JavaScript bundle size**: 8.9KB (previously 98KB with jQuery)\n\n## 🚀 Quick Start\n\nGet up and running in less than 2 minutes:\n\n```bash\n# Clone the repository\ngit clone https://github.com/algolia/sup3rS3cretMes5age.git\ncd sup3rS3cretMes5age\n\n# Start with Docker Compose (recommended)\nmake run\n\n# Access the application\nopen http://localhost:8082\n```\n\nThe service will start with:\n- **Application**: http://localhost:8082\n- **Vault dev server**: In-memory storage with token `supersecret`\n\n### Alternative: Local Build\n\n```bash\n# Start Vault dev server\ndocker run -d --name vault-dev -p 8200:8200 \\\n  -e VAULT_DEV_ROOT_TOKEN_ID=supersecret \\\n  hashicorp/vault:latest\n\n# Build and run the application\ngo build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go\nVAULT_ADDR=http://localhost:8200 \\\nVAULT_TOKEN=supersecret \\\nSUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=\":8080\" \\\n./sup3rs3cret\n```\n\n## Deployment\n\n### Local Development\n\n#### Using Make (Recommended)\n\n```bash\nmake run         # Start services (Vault + App)\nmake logs        # View logs\nmake stop        # Stop services\nmake clean       # Remove containers\n```\n\n#### Using Docker Compose Directly\n\n```bash\ndocker compose -f deploy/docker-compose.yml up --build -d\n```\n\nBy default, the application runs on **port 8082** in HTTP mode: [http://localhost:8082](http://localhost:8082)\n\n💡 You can modify `deploy/docker-compose.yml` to enable HTTPS, HTTP redirection, or change ports. See [Configuration options](#configuration-options).\n\n### Production Deployment\n\nThe image is available at:\n- **Docker Hub**: `algolia/supersecretmessage:latest`\n- **Platforms**: linux/amd64, linux/arm64\n\n#### Docker Image\n\nBuild multi-platform images with SBOM and provenance attestations:\n\n```bash\n# Build for multiple architectures\nmake image\n# Builds: linux/amd64, linux/arm64 with SBOM and provenance\n```\n\n#### AWS Deployment\n\nFor detailed step-by-step instructions on deploying to AWS, see our comprehensive [AWS Deployment Guide](AWS_DEPLOYMENT.md). The guide covers:\n\n- **ECS with Fargate** (recommended) - Serverless containers with Application Load Balancer\n- **EKS (Kubernetes)** - Using the provided Helm chart on Amazon EKS  \n- **EC2 with Docker** - Simple deployment using Docker Compose\n\n```bash\n# Build for multiple architectures\nmake image\n# Builds: linux/amd64, linux/arm64 with SBOM and provenance\n```\n\n#### Deployment Platforms\n\nDeploy using your preferred orchestration tool:\n\n| Platform | Documentation |\n|----------|---------------|\n| Kubernetes | See [Helm Chart](#helm) below |\n| Docker Swarm | Use the provided `docker-compose.yml` |\n| AWS ECS | Use the Docker image with ECS task definition |\n\n**Important**: Deploy alongside a production Vault server. Configure via environment variables:\n- `VAULT_ADDR`: Your Vault server URL\n- `VAULT_TOKEN`: Vault authentication token\n\nSee [configuration examples](#configuration-examples) below.\n\n### 🔒 Security Notice\n\n> ⚠️ **Critical**: Always run this service behind SSL/TLS in production. Secrets sent over HTTP are vulnerable to interception!\n\n#### TLS Termination Options\n\n**Option 1: Inside the Container** (Recommended for simplicity)\n- Configure via environment variables\n- Automatic Let's Encrypt certificates\n- See [Configuration examples - TLS](#tls)\n\n**Option 2: External Load Balancer/Reverse Proxy**\n- Simpler certificate management\n- Offload TLS processing\n- **Ensure secure network** between proxy and container\n- Examples: AWS ALB, Nginx, Traefik, Cloudflare\n\n#### Security Best Practices\n\n- ✅ Use HTTPS/TLS in production\n- ✅ Use a production Vault server (not dev mode)\n- ✅ Rotate Vault tokens regularly\n- ✅ Enable rate limiting (built-in: 10 req/s)\n- ✅ Monitor Vault audit logs\n- ✅ Use strong Vault policies\n- ✅ Keep dependencies updated\n\n## Helm\n\nDeploy to Kubernetes using the included Helm chart:\n\n```bash\nhelm install supersecret ./deploy/charts/supersecretmessage \\\n  --set config.vault.address=http://vault.default.svc.cluster.local:8200 \\\n  --set config.vault.token_secret.name=vault-token\n```\n\n**Chart Details**:\n- Chart Version: 0.1.0\n- App Version: 0.2.5\n- Includes: Deployment, Service, Ingress, HPA, ServiceAccount\n\nFor full documentation, see the [Helm Chart README](deploy/charts/README.md)\n\n## 📡 API Reference\n\n### Create Secret Message\n\n**Endpoint**: `POST /secret`\n\n**Content-Type**: `multipart/form-data`\n\n**Parameters**:\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `msg` | string | Yes | The secret message content |\n| `ttl` | string | No | Time-to-live (default: 48h, max: 168h) |\n| `file` | file | No | File to upload (max 50MB) |\n\n**Response**:\n```json\n{\n  \"token\": \"s.abc123def456\",\n  \"filetoken\": \"s.xyz789uvw012\",  // If file uploaded\n  \"filename\": \"secret.pdf\"        // If file uploaded\n}\n```\n\n**Example**:\n```bash\n# Text message\ncurl -X POST -F 'msg=This is a secret' http://localhost:8082/secret\n\n# With custom TTL\ncurl -X POST -F 'msg=Short-lived secret' -F 'ttl=1h' http://localhost:8082/secret\n\n# With file\ncurl -X POST -F 'msg=Check this file' -F 'file=@secret.pdf' http://localhost:8082/secret\n```\n\n### Retrieve Secret Message\n\n**Endpoint**: `GET /secret?token=<token>`\n\n**Parameters**:\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `token` | string | Yes | The token from POST response |\n\n**Response**:\n```json\n{\n  \"msg\": \"This is a secret\"\n}\n```\n\n**Example**:\n```bash\ncurl \"http://localhost:8082/secret?token=s.abc123def456\"\n```\n\n⚠️ **Note**: After retrieval, the message and token are permanently deleted. Second attempts will fail.\n\n### Health Check\n\n**Endpoint**: `GET /health`\n\n**Response**: `OK` (HTTP 200)\n\n## Command Line Usage\n\nFor convenient command line integration and automation, see our comprehensive [CLI Guide](CLI.md) which includes shell functions for Bash, Zsh, Fish, and WSL.\n\nQuick example:\n```bash\n# Add to your ~/.bashrc or ~/.zshrc\no() { cat \"$@\" | curl -sF 'msg=<-' https://your-domain.com/secret | jq -r .token | awk '{print \"https://your-domain.com/getmsg?token=\"$1}'; }\n\n# Usage\necho \"secret message\" | o\no secret-file.txt\n```\n\n## Configuration options\n\n* `VAULT_ADDR`: address of the Vault server used for storing the temporary secrets.\n* `VAULT_TOKEN`: Vault token used to authenticate to the Vault server.\n* `SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS`: HTTP binding address (e.g. `:80`).\n* `SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS`: HTTPS binding address (e.g. `:443`).\n* `SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED`: whether to enable HTTPS redirection or not (e.g. `true`).\n* `SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN`: domain to use for \"Auto\" TLS, i.e. automatic generation of certificate with Let's Encrypt. See [Configuration examples - TLS - Auto TLS](#auto-tls).\n* `SUPERSECRETMESSAGE_TLS_CERT_FILEPATH`: certificate filepath to use for \"manual\" TLS.\n* `SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH`: certificate key filepath to use for \"manual\" TLS.\n* `SUPERSECRETMESSAGE_VAULT_PREFIX`: vault prefix for secrets (default `cubbyhole/`)\n\n## Configuration examples\n\nHere is an example of a functionnal docker-compose.yml file\n```yaml\nversion: '3.2'\n\nservices:\n  vault:\n    image: vault:latest\n    container_name: vault\n    environment:\n      VAULT_DEV_ROOT_TOKEN_ID: root\n    cap_add:\n      - IPC_LOCK\n    expose:\n      - 8200\n\n  supersecret:\n    build: ./\n    image: algolia/supersecretmessage:latest\n    container_name: supersecret\n    environment:\n      VAULT_ADDR: http://vault:8200\n      VAULT_TOKEN: root\n      SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS: \":80\"\n      SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS: \":443\"\n      SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED: \"true\"\n      SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN: secrets.example.com\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    depends_on:\n      - vault\n```\n\n### Configuration types\n\n#### Plain HTTP\n\n```bash\nVAULT_ADDR=http://vault:8200\nVAULT_TOKEN=root\n\nSUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=:80\n```\n\n#### TLS\n\n##### Auto TLS\n\n```bash\nVAULT_ADDR=http://vault:8200\nVAULT_TOKEN=root\n\nSUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443\nSUPERSECRETMESSAGE_TLS_AUTO_DOMAIN=secrets.example.com\n```\n\n##### Auto TLS with HTTP > HTTPS redirection\n\n```bash\nVAULT_ADDR=http://vault:8200\nVAULT_TOKEN=root\n\nSUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=:80\nSUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443\nSUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED=true\nSUPERSECRETMESSAGE_TLS_AUTO_DOMAIN=secrets.example.com\n```\n\n##### Manual TLS\n\n```bash\nVAULT_ADDR=http://vault:8200\nVAULT_TOKEN=root\n\nSUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=:443\nSUPERSECRETMESSAGE_TLS_CERT_FILEPATH=/mnt/ssl/cert_secrets.example.com.pem\nSUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH=/mnt/ssl/key_secrets.example.com.pem\n```\n\n## 📸 Screenshots\n\n### Message Creation Interface\n![supersecretmsg](https://github.com/user-attachments/assets/0ada574b-99e4-4562-aea4-a1868d6ca0d8)\n\n*Clean, intuitive interface for creating self-destructing messages with optional file uploads and custom TTL.*\n\n### Message Retrieval Interface\n![supersecretmsg](https://github.com/user-attachments/assets/6d0c455f-00ca-430e-bc8c-e721e071843a\")\n\n*Simple, secure interface for viewing self-destructing messages that are permanently deleted upon retrieval.*\n\n## 🛠️ Development\n\n### Prerequisites\n\n- Go 1.25.1 or later\n- Docker (for Vault dev server)\n- Make (optional, for convenience)\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/algolia/sup3rS3cretMes5age.git\ncd sup3rS3cretMes5age\n\n# Download dependencies\ngo mod download\n\n# Build the binary\ngo build -o sup3rs3cret cmd/sup3rS3cretMes5age/main.go\n```\n\n### Running Tests\n\n```bash\n# Run all tests\nmake test\n\n# Or directly with go\ngo test ./... -v\n```\n\n### Code Quality\n\n```bash\n# Format code\ngofmt -s -w .\n\n# Lint\ngolangci-lint run --timeout 300s\n\n# Static analysis\ngo vet ./...\n```\n\n### Project Structure\n\n```\n.\n├── cmd/sup3rS3cretMes5age/    # Application entry point\n│   └── main.go               # (23 lines)\n├── internal/                  # Core business logic\n│   ├── config.go             # Configuration (77 lines)\n│   ├── handlers.go           # HTTP handlers (88 lines)\n│   ├── server.go             # Server setup (94 lines)\n│   └── vault.go              # Vault integration (174 lines)\n├── web/static/               # Frontend assets\n│   ├── index.html           # Message creation page\n│   ├── getmsg.html          # Message retrieval page\n│   ├── application.css      # Styling\n│   └── clipboard-2.0.11.min.js\n├── deploy/                   # Deployment configs\n│   ├── Dockerfile           # Multi-stage build\n│   ├── docker-compose.yml   # Local dev stack\n│   └── charts/              # Helm chart\n└── Makefile                 # Build automation\n```\n\n**Total Code**: 609 lines of Go across 7 files\n\n## Contributing\n\nContributions are welcome! 🎉\n\n### How to Contribute\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n### Guidelines\n\n- Write tests for new features\n- Follow existing code style\n- Update documentation as needed\n- Ensure all tests pass (`make test`)\n- Run linters (`golangci-lint run`)\n\nAll pull requests will be reviewed by the Algolia team.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\nThis project is built on the shoulders of giants:\n\n- **[HashiCorp Vault](https://www.vaultproject.io/)** - Secure secret storage backend\n- **[Echo](https://echo.labstack.com/)** - High performance Go web framework\n- **[Let's Encrypt](https://letsencrypt.org/)** - Free SSL/TLS certificates\n- **[ClipboardJS](https://clipboardjs.com/)** - Modern clipboard functionality\n"
  },
  {
    "path": "cmd/sup3rS3cretMes5age/main.go",
    "content": "// Package main provides the entry point for the sup3rS3cretMes5age application,\n// a secure self-destructing message service using HashiCorp Vault as a backend.\npackage main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/algolia/sup3rS3cretMes5age/internal\"\n)\n\n// version holds the application version string, injected at build time via ldflags.\nvar version = \"\"\n\nfunc main() {\n\tversionFlag := flag.Bool(\"version\", false, \"Print version\")\n\tflag.Parse()\n\tif *versionFlag {\n\t\tfmt.Println(version)\n\t\tos.Exit(0)\n\t}\n\t// Load configuration\n\tconf := internal.LoadConfig()\n\n\t// Create server with handlers\n\thandlers := internal.NewSecretHandlers(internal.NewVault(\"\", conf.VaultPrefix, \"\"))\n\tserver := internal.NewServer(conf, handlers)\n\n\t// Setup graceful shutdown\n\tctx, cancel := context.WithCancel(context.Background())\n\n\t// Listen for interrupt signals\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)\n\n\t// Start server in goroutine\n\tgo func() {\n\t\tif err := server.Start(ctx); err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"Server error: %v\\n\", err)\n\t\t\tos.Exit(1)\n\t\t}\n\t}()\n\n\t// Wait for interrupt signal\n\t<-sigChan\n\tfmt.Println(\"\\nShutting down gracefully...\")\n\n\t// Cancel context to signal server to stop\n\tcancel()\n\n\t// Give server 10 seconds to finish existing requests\n\tshutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)\n\tdefer shutdownCancel()\n\n\tif err := server.Shutdown(shutdownCtx); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Shutdown error: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Println(\"Server stopped successfully\")\n}\n"
  },
  {
    "path": "deploy/Dockerfile",
    "content": "FROM golang:1.26 AS builder\n\nWORKDIR /go/src/github.com/algolia/sup3rS3cretMes5age\n\nARG VERSION\nARG BUILD_DATE\nARG VCS_REF\n\n# Add security-related labels\nLABEL org.opencontainers.image.title=\"sup3rS3cretMes5age\" \\\n      org.opencontainers.image.description=\"Secure self-destructing message service\" \\\n      org.opencontainers.image.version=\"${VERSION}\" \\\n      org.opencontainers.image.created=\"${BUILD_DATE}\" \\\n      org.opencontainers.image.revision=\"${VCS_REF}\" \\\n      org.opencontainers.image.vendor=\"Algolia\" \\\n      org.opencontainers.image.licenses=\"MIT\"\n\nCOPY . .\n\n# build process\nRUN go mod download\nRUN CGO_ENABLED=0 GOOS=linux go build \\\n    -trimpath \\\n    -a \\\n    -ldflags \"-X main.version=${VERSION} -s -w -extldflags '-static'\" \\\n    -o /tmp/sup3rS3cretMes5age \\\n    cmd/sup3rS3cretMes5age/main.go\n\n# Multi-stage build with security hardening\nFROM alpine:latest\n\n# Install only necessary certificates and packages\nRUN apk add --no-cache \\\n    ca-certificates \\\n    tzdata \\\n    curl \\\n    && rm -rf /var/cache/apk/*\n\n# Create non-root user with restricted permissions\nRUN addgroup -S -g 1001 supersecret \\\n    && adduser -S -u 1001 -G supersecret supersecret\n\n# Set up working directory with restricted permissions\nWORKDIR /opt/supersecret\n\n# Copy binary and static assets\nCOPY --from=builder --chown=supersecret:supersecret /tmp/sup3rS3cretMes5age ./sup3rS3cretMes5age\nCOPY --chown=supersecret:supersecret web/static/ ./static/\n\n# Set proper file permissions\nRUN chmod 755 ./sup3rS3cretMes5age \\\n    && chmod 644 ./static/* \\\n    && find ./static -type d -exec chmod 755 {} \\;\n\n# Define environment variables\nENV \\\n    VAULT_ADDR=\"\" \\\n    VAULT_TOKEN=\"\" \\\n    SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS=\":8082\" \\\n    SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS=\"\" \\\n    SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED=\"false\" \\\n    SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN=\"\" \\\n    SUPERSECRETMESSAGE_TLS_CERT_FILEPATH=\"\" \\\n    SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH=\"\" \\\n    SUPERSECRETMESSAGE_VAULT_PREFIX=\"cubbyhole/\" \\\n    GODEBUG=x509ignoreCN=0 \\\n    GOGC=200 \\\n    GOMAXPROCS=1\n\nUSER supersecret\n\n# Expose only necessary ports\nEXPOSE 8082\n\nENTRYPOINT [\"/opt/supersecret/sup3rS3cretMes5age\"]\nCMD []\n"
  },
  {
    "path": "deploy/charts/README.md",
    "content": "# Supersecretmessage Helm Chart\n\nThis repository contains the Supersecretmessage Helm chart for installing\nand configuring Supersecretmessage on Kubernetes. This chart supports multiple use\ncases of Supersecretmessage on Kubernetes depending on the values provided.\n\n## Prerequisites\n\nTo use the charts here, [Helm](https://helm.sh/) and [Vault](https://www.vaultproject.io/) must be configured for your\nKubernetes cluster.\n\nThe versions required are:\n\n* **Helm 3.6+**\n* **Vault 1.10+**\n* **Kubernetes 1.22+** - This is the earliest version of Kubernetes tested.\n  It is possible that this chart works with earlier versions but it is\n  untested.\n\n> :warning: **Please note**: Setting up Kubernetes, Helm and Vault is outside the scope of\nthis README. Please refer to the [Kubernetes](https://kubernetes.io/docs/home/), [Helm](https://helm.sh/docs/intro/install/) and [Vault](https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-raft-deployment-guide) documentation. You can install the last one as a [Chart](https://developer.hashicorp.com/vault/docs/platform/k8s/helm).\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/.helmignore",
    "content": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation (prefixed with !). Only one pattern per line.\n.DS_Store\n# Common VCS dirs\n.git/\n.gitignore\n.bzr/\n.bzrignore\n.hg/\n.hgignore\n.svn/\n# Common backup files\n*.swp\n*.bak\n*.tmp\n*.orig\n*~\n# Various IDEs\n.project\n.idea/\n*.tmproj\n.vscode/\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/Chart.yaml",
    "content": "apiVersion: v2\nname: supersecretmessage\ndescription: A Helm chart for Kubernetes\n\n# A chart can be either an 'application' or a 'library' chart.\n#\n# Application charts are a collection of templates that can be packaged into versioned archives\n# to be deployed.\n#\n# Library charts provide useful utilities or functions for the chart developer. They're included as\n# a dependency of application charts to inject those utilities and functions into the rendering\n# pipeline. Library charts do not define any templates and therefore cannot be deployed.\ntype: application\n\n# This is the chart version. This version number should be incremented each time you make changes\n# to the chart and its templates, including the app version.\n# Versions are expected to follow Semantic Versioning (https://semver.org/)\nversion: 0.1.0\n\n# This is the version number of the application being deployed. This version number should be\n# incremented each time you make changes to the application. Versions are not expected to\n# follow Semantic Versioning. They should reflect the version the application is using.\n# It is recommended to use it with quotes.\nappVersion: \"0.2.5\"\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/NOTES.txt",
    "content": "1. Get the application URL by running these commands:\n{{- if .Values.ingress.enabled }}\n{{- range $host := .Values.ingress.hosts }}\n  {{- range .paths }}\n  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}\n  {{- end }}\n{{- end }}\n{{- else if contains \"NodePort\" .Values.service.type }}\n  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath=\"{.spec.ports[0].nodePort}\" services {{ include \"supersecretmessage.fullname\" . }})\n  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n  echo http://$NODE_IP:$NODE_PORT\n{{- else if contains \"LoadBalancer\" .Values.service.type }}\n     NOTE: It may take a few minutes for the LoadBalancer IP to be available.\n           You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include \"supersecretmessage.fullname\" . }}'\n  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include \"supersecretmessage.fullname\" . }} --template \"{{\"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}\"}}\")\n  echo http://$SERVICE_IP:{{ .Values.service.port }}\n{{- else if contains \"ClusterIP\" .Values.service.type }}\n  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l \"app.kubernetes.io/name={{ include \"supersecretmessage.name\" . }},app.kubernetes.io/instance={{ .Release.Name }}\" -o jsonpath=\"{.items[0].metadata.name}\")\n  export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath=\"{.spec.containers[0].ports[0].containerPort}\")\n  echo \"Visit http://127.0.0.1:80 to use your application\"\n  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 80:$CONTAINER_PORT\n{{- end }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/_helpers.tpl",
    "content": "{{/*\nExpand the name of the chart.\n*/}}\n{{- define \"supersecretmessage.name\" -}}\n{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n\n{{/*\nCreate a default fully qualified app name.\nWe truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).\nIf release name contains chart name it will be used as a full name.\n*/}}\n{{- define \"supersecretmessage.fullname\" -}}\n{{- if .Values.fullnameOverride }}\n{{- .Values.fullnameOverride | trunc 63 | trimSuffix \"-\" }}\n{{- else }}\n{{- $name := default .Chart.Name .Values.nameOverride }}\n{{- if contains $name .Release.Name }}\n{{- .Release.Name | trunc 63 | trimSuffix \"-\" }}\n{{- else }}\n{{- printf \"%s-%s\" .Release.Name $name | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n{{- end }}\n{{- end }}\n\n{{/*\nCreate chart name and version as used by the chart label.\n*/}}\n{{- define \"supersecretmessage.chart\" -}}\n{{- printf \"%s-%s\" .Chart.Name .Chart.Version | replace \"+\" \"_\" | trunc 63 | trimSuffix \"-\" }}\n{{- end }}\n\n{{/*\nCommon labels\n*/}}\n{{- define \"supersecretmessage.labels\" -}}\nhelm.sh/chart: {{ include \"supersecretmessage.chart\" . }}\n{{ include \"supersecretmessage.selectorLabels\" . }}\n{{- if .Chart.AppVersion }}\napp.kubernetes.io/version: {{ .Chart.AppVersion | quote }}\n{{- end }}\napp.kubernetes.io/managed-by: {{ .Release.Service }}\n{{- end }}\n\n{{/*\nSelector labels\n*/}}\n{{- define \"supersecretmessage.selectorLabels\" -}}\napp.kubernetes.io/name: {{ include \"supersecretmessage.name\" . }}\napp.kubernetes.io/instance: {{ .Release.Name }}\n{{- end }}\n\n{{/*\nCreate the name of the service account to use\n*/}}\n{{- define \"supersecretmessage.serviceAccountName\" -}}\n{{- if .Values.serviceAccount.create }}\n{{- default (include \"supersecretmessage.fullname\" .) .Values.serviceAccount.name }}\n{{- else }}\n{{- default \"default\" .Values.serviceAccount.name }}\n{{- end }}\n{{- end }}\n\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"supersecretmessage.fullname\" . }}\n  labels:\n    {{- include \"supersecretmessage.labels\" . | nindent 4 }}\nspec:\n  {{- if not .Values.autoscaling.enabled }}\n  replicas: {{ .Values.replicaCount }}\n  {{- end }}\n  {{- with .Values.strategy }}\n  strategy:\n    {{- toYaml . | nindent 4 }}\n  {{- end }}\n  selector:\n    matchLabels:\n      {{- include \"supersecretmessage.selectorLabels\" . | nindent 6 }}\n  template:\n    metadata:\n      {{- with .Values.podAnnotations }}\n      annotations:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      labels:\n        {{- include \"supersecretmessage.labels\" . | nindent 8 }}\n        {{- with .Values.podLabels }}\n        {{- toYaml . | nindent 8 }}\n        {{- end }}\n    spec:\n      {{- with .Values.imagePullSecrets }}\n      imagePullSecrets:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.hostAliases }}\n      hostAliases:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.serviceAccountName }}\n      serviceAccountName: {{ .Values.serviceAccountName }}\n      {{- end }}\n      serviceAccountName: {{ include \"supersecretmessage.serviceAccountName\" . }}\n      {{- with .Values.podSecurityContext }}\n      securityContext:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.priorityClassName }}\n      priorityClassName: {{ . }}\n      {{- end }}\n      {{- if .Values.terminationGracePeriodSeconds }}\n      terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}\n      {{- end }}\n      containers:\n        - name: {{ .Chart.Name }}\n          {{- with .Values.securityContext }}\n          securityContext:\n            {{- toYaml .Values.securityContext | nindent 12 }}\n          {{- end }}\n          image: \"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}\"\n          imagePullPolicy: {{ .Values.image.pullPolicy }}\n          env:\n            {{- with .Values.config.vault }}\n          - name: VAULT_ADDR\n            value: {{ .address | default \"http://vault:8200\" }}\n            {{- end }}\n            {{- with .Values.config.vault.token_secret }}\n          - name: VAULT_TOKEN\n            valueFrom:\n              secretKeyRef:\n                name: {{ .name }}\n                key: {{ .key }}\n            {{- end }}\n            {{- with .Values.config.server.env }}\n              {{- toYaml . | nindent 10 }}\n            {{- end }}\n          {{- with .Values.envFrom }}\n          envFrom:\n            {{- toYaml . | nindent 10 }}\n          {{- end }}\n          ports:\n            - name: http\n              containerPort: {{ .Values.service.port | default \"80\"}}\n              protocol: TCP\n          {{- with .Values.livenessProbe }}\n          livenessProbe:\n            httpGet:\n              path: {{ .path }}\n              port: {{ .port | default \"http\" }}\n              scheme: {{ .scheme | default \"HTTP\" }}\n            failureThreshold: {{ .failureThreshold }}\n            initialDelaySeconds: {{ .initialDelaySeconds }}\n            periodSeconds: {{ .periodSeconds }}\n            successThreshold: {{ .successThreshold }}\n            timeoutSeconds: {{ .timeoutSeconds }}\n          {{- end }}\n          {{- with .Values.readinessProbe }}\n          readinessProbe:\n            httpGet:\n              path: {{ .path }}\n              port: {{ .port | default \"http\" }}\n              scheme: {{ .scheme | default \"HTTP\" }}\n            failureThreshold: {{ .failureThreshold }}\n            initialDelaySeconds: {{ .initialDelaySeconds }}\n            periodSeconds: {{ .periodSeconds }}\n            successThreshold: {{ .successThreshold }}\n            timeoutSeconds: {{ .timeoutSeconds }}\n          {{- end }}\n          resources:\n            {{- toYaml .Values.resources | nindent 12 }}\n          {{- with .Values.volumeMounts }}\n          volumeMounts:\n            {{- toYaml . | nindent 12 }}\n          {{- end }}\n      {{- with .Values.volumes }}\n      volumes:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.nodeSelector }}\n      nodeSelector:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.affinity }}\n      affinity:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n      {{- with .Values.tolerations }}\n      tolerations:\n        {{- toYaml . | nindent 8 }}\n      {{- end }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/hpa.yaml",
    "content": "{{- if .Values.autoscaling.enabled }}\napiVersion: autoscaling/v2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: {{ include \"supersecretmessage.fullname\" . }}\n  labels:\n    {{- include \"supersecretmessage.labels\" . | nindent 4 }}\nspec:\n  scaleTargetRef:\n    apiVersion: apps/v1\n    kind: Deployment\n    name: {{ include \"supersecretmessage.fullname\" . }}\n  minReplicas: {{ .Values.autoscaling.minReplicas }}\n  maxReplicas: {{ .Values.autoscaling.maxReplicas }}\n  metrics:\n    {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}\n    {{- end }}\n    {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}\n    - type: Resource\n      resource:\n        name: memory\n        target:\n          type: Utilization\n          averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}\n    {{- end }}\n{{- end }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/ingress.yaml",
    "content": "{{- if .Values.ingress.enabled -}}\n{{- $fullName := include \"supersecretmessage.fullname\" . -}}\n{{- $svcPort := .Values.service.port -}}\n{{- if and .Values.ingress.className (not (semverCompare \">=1.18-0\" .Capabilities.KubeVersion.GitVersion)) }}\n  {{- if not (hasKey .Values.ingress.annotations \"kubernetes.io/ingress.class\") }}\n  {{- $_ := set .Values.ingress.annotations \"kubernetes.io/ingress.class\" .Values.ingress.className}}\n  {{- end }}\n{{- end }}\n{{- if semverCompare \">=1.19-0\" .Capabilities.KubeVersion.GitVersion -}}\napiVersion: networking.k8s.io/v1\n{{- else if semverCompare \">=1.14-0\" .Capabilities.KubeVersion.GitVersion -}}\napiVersion: networking.k8s.io/v1beta1\n{{- else -}}\napiVersion: extensions/v1beta1\n{{- end }}\nkind: Ingress\nmetadata:\n  name: {{ $fullName }}\n  labels:\n    {{- include \"supersecretmessage.labels\" . | nindent 4 }}\n  {{- with .Values.ingress.annotations }}\n  annotations:\n    {{- toYaml . | nindent 4 }}\n  {{- end }}\nspec:\n  {{- if and .Values.ingress.className (semverCompare \">=1.18-0\" .Capabilities.KubeVersion.GitVersion) }}\n  ingressClassName: {{ .Values.ingress.className }}\n  {{- end }}\n  {{- if .Values.ingress.tls }}\n  tls:\n    {{- range .Values.ingress.tls }}\n    - hosts:\n        {{- range .hosts }}\n        - {{ . | quote }}\n        {{- end }}\n      secretName: {{ .secretName }}\n    {{- end }}\n  {{- end }}\n  rules:\n    {{- range .Values.ingress.hosts }}\n    - host: {{ .host | quote }}\n      http:\n        paths:\n          {{- range .paths }}\n          - path: {{ .path }}\n            {{- if and .pathType (semverCompare \">=1.18-0\" $.Capabilities.KubeVersion.GitVersion) }}\n            pathType: {{ .pathType }}\n            {{- end }}\n            backend:\n              {{- if semverCompare \">=1.19-0\" $.Capabilities.KubeVersion.GitVersion }}\n              service:\n                name: {{ $fullName }}\n                port:\n                  number: {{ $svcPort }}\n              {{- else }}\n              serviceName: {{ $fullName }}\n              servicePort: {{ $svcPort }}\n              {{- end }}\n          {{- end }}\n    {{- end }}\n{{- end }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: {{ include \"supersecretmessage.fullname\" . }}\n  labels:\n    {{- include \"supersecretmessage.labels\" . | nindent 4 }}\nspec:\n  type: {{ .Values.service.type }}\n  ports:\n    - port: {{ .Values.service.port }}\n      targetPort: http\n      protocol: TCP\n      name: http\n  selector:\n    {{- include \"supersecretmessage.selectorLabels\" . | nindent 4 }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/templates/serviceaccount.yaml",
    "content": "{{- if .Values.serviceAccount.create -}}\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: {{ include \"supersecretmessage.serviceAccountName\" . }}\n  labels:\n    {{- include \"supersecretmessage.labels\" . | nindent 4 }}\n  {{- with .Values.serviceAccount.annotations }}\n  annotations:\n    {{- toYaml . | nindent 4 }}\n  {{- end }}\nautomountServiceAccountToken: {{ .Values.serviceAccount.automount }}\n{{- end }}\n"
  },
  {
    "path": "deploy/charts/supersecretmessage/values.yaml",
    "content": "# Default values for supersecretmessage.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\nreplicaCount: 1\n\nimage:\n  repository: algolia/supersecretmessage\n  pullPolicy: IfNotPresent\n  # Overrides the image tag whose default is the chart appVersion.\n  tag: \"0.2.5\"\n\nconfig:\n  vault:\n    # address of the Vault server used for storing the temporary secrets, Example: http://vault:8200\n    address: \"http://vault.svc.cluster.local:8200\"\n    # Vault Token secret for connect\n    token_secret:\n      name: \"vault-token\"\n      key: \"token\"\n  server:\n    env:\n    # HTTP binding address (e.g. :80).\n    - name: SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS\n      value: \":80\"\n    # HTTPS binding address (e.g. :443).\n    - name: SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS\n      value: \"\"\n      # whether to enable HTTPS redirection or not (e.g. true).\n    - name: SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED\n      value: \"false\"\n      # domain to use for \"Auto\" TLS, i.e. automatic generation of certificate with Let's Encrypt. See Configuration examples - TLS - Auto TLS.\n    - name: SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN\n      value: \"\"\n      # certificate filepath to use for \"manual\" TLS.\n    - name: SUPERSECRETMESSAGE_TLS_CERT_FILEPATH\n      value: \"\"\n      # certificate key filepath to use for \"manual\" TLS.\n    - name: SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH\n      value: \"\"\n      # vault prefix for secrets (default cubbyhole/)\n    - name: SUPERSECRETMESSAGE_VAULT_PREFIX\n      value: \"cubbyhole/\"\n\n# Used to define custom livenessProbe settings\nlivenessProbe:\n  # It it the same that .Values.config.server.env. \"SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS\"\n  port: \"80\"\n  # Path of probe\n  path: \"/msg\"\n  # When a probe fails, Kubernetes will try failureThreshold times before giving up\n  failureThreshold: 2\n  # Number of seconds after the container has started before probe initiates\n  initialDelaySeconds: 5\n  # How often (in seconds) to perform the probe\n  periodSeconds: 10\n  # Minimum consecutive successes for the probe to be considered successful after having failed\n  successThreshold: 1\n  # Number of seconds after which the probe times out.\n  timeoutSeconds: 5\n  scheme: \"HTTP\"\n# Used to define custom readinessProbe settings\nreadinessProbe:\n  # It it the same that .Values.config.server.env. \"SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS\"\n  port: \"80\"\n  # Path of probe\n  path: \"/msg\"\n  # When a probe fails, Kubernetes will try failureThreshold times before giving up\n  failureThreshold: 2\n  # Number of seconds after the container has started before probe initiates\n  initialDelaySeconds: 5\n  # How often (in seconds) to perform the probe\n  periodSeconds: 10\n  # Minimum consecutive successes for the probe to be considered successful after having failed\n  successThreshold: 1\n  # Number of seconds after which the probe times out.\n  timeoutSeconds: 5\n  scheme: \"HTTP\"\n\nimagePullSecrets: []\nnameOverride: \"\"\nfullnameOverride: \"\"\n\nserviceAccount:\n  # Specifies whether a service account should be created\n  create: false\n  # Automatically mount a ServiceAccount's API credentials?\n  automount: true\n  # Annotations to add to the service account\n  annotations: {}\n  # The name of the service account to use.\n  # If not set and create is true, a name is generated using the fullname template\n  name: \"\"\n\nstrategy:\n  type: Recreate\n\nenvFrom: []\npodAnnotations: {}\npodLabels: {}\nhostAliases: []\nterminationGracePeriodSeconds: \"\"\npriorityClassName: \"\"\npodSecurityContext: {} # Optional\n  # fsGroup: 2000\n\nsecurityContext: {} # Optional\n  # capabilities:\n  #   drop:\n  #   - ALL\n  # readOnlyRootFilesystem: true\n  # runAsNonRoot: true\n  # runAsUser: 1000\n\nservice:\n  type: ClusterIP\n  port: 80\n\ningress:\n  enabled: false\n  className: \"\"\n  annotations: {}\n    # kubernetes.io/ingress.class: supersecretmessage\n    # kubernetes.io/tls-acme: \"true\"\n  hosts:\n    - host: chart-example.local\n      paths:\n        - path: /\n          pathType: ImplementationSpecific\n  tls: []\n  #  - secretName: chart-example-tls\n  #    hosts:\n  #      - chart-example.local\n\nresources:\n  limits:\n    cpu: 300m\n    memory: 512Mi\n  requests:\n    cpu: 20m\n    memory: 64Mi\n  # We usually recommend not to specify default resources and to leave this as a conscious\n  # choice for the user. This also increases chances charts run on environments with little\n  # resources, such as Minikube. If you do want to specify resources, uncomment the following\n  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n  # limits:\n  #   cpu: 100m\n  #   memory: 128Mi\n  # requests:\n  #   cpu: 100m\n  #   memory: 128Mi\n\nautoscaling:\n  enabled: false\n  minReplicas: 1\n  maxReplicas: 100\n  targetCPUUtilizationPercentage: 80\n  # targetMemoryUtilizationPercentage: 80\n\n# Additional volumes on the output Deployment definition.\nvolumes: [] # Optional\n# - name: foo\n#   secret:\n#     secretName: mysecret\n#     optional: false\n\n# Additional volumeMounts on the output Deployment definition.\nvolumeMounts: [] # Optional\n# - name: foo\n#   mountPath: \"/etc/foo\"\n#   readOnly: true\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n"
  },
  {
    "path": "deploy/docker-compose.yml",
    "content": "version: '3.8'\n\nservices:\n  vault:\n    image: hashicorp/vault:latest\n    container_name: vault\n    environment:\n      VAULT_DEV_ROOT_TOKEN_ID: supersecret\n      VAULT_DEV_LISTEN_ADDRESS: \"0.0.0.0:8200\"\n    cap_add:\n      - IPC_LOCK\n    security_opt:\n      - no-new-privileges:true\n      - seccomp=unconfined\n    tmpfs:\n      - /tmp\n      - /dev/shm\n    networks:\n      - secure-network\n    # Security-focused health check\n    healthcheck:\n      test: [\"CMD\", \"vault\", \"status\", \"-address=http://localhost:8200\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n\n  supersecret:\n    build:\n      context: ../\n      dockerfile: deploy/Dockerfile\n    image: algolia/supersecretmessage:latest\n    container_name: supersecret\n    environment:\n      VAULT_ADDR: http://vault:8200\n      VAULT_TOKEN: supersecret\n      SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS: \":8082\"\n      SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED: \"false\"\n      # Security-focused environment variables\n      GODEBUG: \"x509ignoreCN=0\"\n      GOGC: \"200\"\n      GOMAXPROCS: \"1\"\n    security_opt:\n      - no-new-privileges:true\n      - apparmor=unconfined\n      - seccomp=unconfined\n    read_only: true\n    # Mount only necessary directories as read-only\n    tmpfs:\n      - /tmp\n    ports:\n      - \"8082:8082\"\n    depends_on:\n      - vault\n    networks:\n      - secure-network\n    # Enhanced security configurations\n    sysctls:\n      - net.ipv4.conf.all.rp_filter=1\n      - net.ipv4.conf.all.secure_redirects=0\n    ulimits:\n      nproc: 65536\n      nofile: 65536\n    # Security-focused health check\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-sf\", \"http://localhost:8082/health\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n    # Resource limits for security\n    deploy:\n      resources:\n        limits:\n          memory: 512M\n          cpus: \"0.5\"\n        reservations:\n          memory: 256M\n          cpus: \"0.25\"\n\nnetworks:\n  secure-network:\n    driver: bridge\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/algolia/sup3rS3cretMes5age\n\ngo 1.26.1\n\nrequire (\n\tgithub.com/hashicorp/vault v1.21.2\n\tgithub.com/hashicorp/vault/api v1.23.0\n\tgithub.com/labstack/echo/v4 v4.13.4\n\tgithub.com/stretchr/testify v1.11.1\n\tgolang.org/x/crypto v0.49.0\n)\n\nrequire (\n\tcloud.google.com/go v0.121.6 // indirect\n\tcloud.google.com/go/auth v0.16.5 // indirect\n\tcloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect\n\tcloud.google.com/go/cloudsqlconn v1.4.3 // indirect\n\tcloud.google.com/go/compute/metadata v0.9.0 // indirect\n\tcloud.google.com/go/iam v1.5.2 // indirect\n\tcloud.google.com/go/kms v1.23.0 // indirect\n\tcloud.google.com/go/longrunning v0.6.7 // indirect\n\tcloud.google.com/go/monitoring v1.24.2 // indirect\n\tdario.cat/mergo v1.0.2 // indirect\n\tfilippo.io/edwards25519 v1.1.1 // indirect\n\tgithub.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect\n\tgithub.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect\n\tgithub.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // indirect\n\tgithub.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect\n\tgithub.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect\n\tgithub.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect\n\tgithub.com/Azure/go-autorest v14.2.0+incompatible // indirect\n\tgithub.com/Azure/go-autorest/autorest v0.11.29 // indirect\n\tgithub.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect\n\tgithub.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect\n\tgithub.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect\n\tgithub.com/Azure/go-autorest/autorest/date v0.3.0 // indirect\n\tgithub.com/Azure/go-autorest/autorest/to v0.4.0 // indirect\n\tgithub.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect\n\tgithub.com/Azure/go-autorest/logger v0.2.1 // indirect\n\tgithub.com/Azure/go-autorest/tracing v0.6.0 // indirect\n\tgithub.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect\n\tgithub.com/DataDog/datadog-go v3.2.0+incompatible // indirect\n\tgithub.com/Jeffail/gabs/v2 v2.1.0 // indirect\n\tgithub.com/Masterminds/goutils v1.1.1 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.4.0 // indirect\n\tgithub.com/Masterminds/sprig/v3 v3.3.0 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/ProtonMail/go-crypto v1.2.0 // indirect\n\tgithub.com/ProtonMail/gopenpgp/v3 v3.2.1 // indirect\n\tgithub.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect\n\tgithub.com/armon/go-metrics v0.4.1 // indirect\n\tgithub.com/armon/go-radix v1.0.0 // indirect\n\tgithub.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect\n\tgithub.com/aws/aws-sdk-go v1.55.8 // indirect\n\tgithub.com/aws/aws-sdk-go-v2 v1.38.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/config v1.29.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.17.68 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ec2 v1.200.0 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ecs v1.53.8 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.33.20 // indirect\n\tgithub.com/aws/smithy-go v1.22.5 // indirect\n\tgithub.com/benbjohnson/immutable v0.4.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bgentry/speakeasy v0.2.0 // indirect\n\tgithub.com/boltdb/bolt v1.3.1 // indirect\n\tgithub.com/boombuler/barcode v1.0.1 // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect\n\tgithub.com/circonus-labs/circonusllhist v0.1.3 // indirect\n\tgithub.com/cloudflare/circl v1.6.3 // indirect\n\tgithub.com/containerd/errdefs v1.0.0 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/coreos/etcd v3.3.27+incompatible // indirect\n\tgithub.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect\n\tgithub.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect\n\tgithub.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect\n\tgithub.com/digitalocean/godo v1.7.5 // indirect\n\tgithub.com/dimchansky/utfbom v1.1.1 // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/dnaeon/go-vcr v1.2.0 // indirect\n\tgithub.com/docker/docker v28.4.0+incompatible // indirect\n\tgithub.com/docker/go-connections v0.5.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.12.2 // indirect\n\tgithub.com/evanphx/json-patch/v5 v5.9.11 // indirect\n\tgithub.com/fatih/color v1.18.0 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/gammazero/deque v0.2.1 // indirect\n\tgithub.com/gammazero/workerpool v1.1.3 // indirect\n\tgithub.com/go-jose/go-jose/v3 v3.0.4 // indirect\n\tgithub.com/go-jose/go-jose/v4 v4.1.3 // 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-ole/go-ole v1.2.6 // indirect\n\tgithub.com/go-openapi/analysis v0.23.0 // indirect\n\tgithub.com/go-openapi/errors v0.22.1 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.21.0 // indirect\n\tgithub.com/go-openapi/loads v0.22.0 // indirect\n\tgithub.com/go-openapi/spec v0.21.0 // indirect\n\tgithub.com/go-openapi/strfmt v0.23.0 // indirect\n\tgithub.com/go-openapi/swag v0.23.1 // indirect\n\tgithub.com/go-openapi/validate v0.24.0 // indirect\n\tgithub.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect\n\tgithub.com/go-sql-driver/mysql v1.9.3 // indirect\n\tgithub.com/go-test/deep v1.1.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang-jwt/jwt/v4 v4.5.2 // indirect\n\tgithub.com/golang-jwt/jwt/v5 v5.3.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/golang/snappy v1.0.0 // indirect\n\tgithub.com/google/certificate-transparency-go v1.3.2 // indirect\n\tgithub.com/google/gnostic-models v0.7.0 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/go-metrics-stackdriver v0.2.0 // indirect\n\tgithub.com/google/go-querystring v1.1.0 // indirect\n\tgithub.com/google/s2a-go v0.1.9 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.15.0 // indirect\n\tgithub.com/gophercloud/gophercloud v0.1.0 // indirect\n\tgithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect\n\tgithub.com/hashicorp/cli v1.1.7 // indirect\n\tgithub.com/hashicorp/consul/sdk v0.16.2 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/hashicorp/eventlogger v0.2.10 // indirect\n\tgithub.com/hashicorp/go-bexpr v0.1.12 // indirect\n\tgithub.com/hashicorp/go-cleanhttp v0.5.2 // indirect\n\tgithub.com/hashicorp/go-discover v1.1.1-0.20250922102917-55e5010ad859 // indirect\n\tgithub.com/hashicorp/go-discover/provider/gce v0.0.0-20241120163552-5eb1507d16b4 // indirect\n\tgithub.com/hashicorp/go-hclog v1.6.3 // indirect\n\tgithub.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 // indirect\n\tgithub.com/hashicorp/go-immutable-radix v1.3.1 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.1 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/v2 v2.0.18 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.10 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.4 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.11 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault/v2 v2.0.14 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.13 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.9 // indirect\n\tgithub.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.13 // indirect\n\tgithub.com/hashicorp/go-memdb v1.3.5 // indirect\n\tgithub.com/hashicorp/go-metrics v0.5.4 // indirect\n\tgithub.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect\n\tgithub.com/hashicorp/go-multierror v1.1.1 // indirect\n\tgithub.com/hashicorp/go-plugin v1.6.3 // indirect\n\tgithub.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a // indirect\n\tgithub.com/hashicorp/go-retryablehttp v0.7.8 // indirect\n\tgithub.com/hashicorp/go-rootcerts v1.0.2 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/base62 v0.1.2 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.1 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/mlock v0.1.3 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/permitpool v1.0.0 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/regexp v1.0.0 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect\n\tgithub.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3 // indirect\n\tgithub.com/hashicorp/go-sockaddr v1.0.7 // indirect\n\tgithub.com/hashicorp/go-syslog v1.0.0 // indirect\n\tgithub.com/hashicorp/go-uuid v1.0.3 // indirect\n\tgithub.com/hashicorp/go-version v1.7.0 // indirect\n\tgithub.com/hashicorp/golang-lru v1.0.2 // indirect\n\tgithub.com/hashicorp/golang-lru/v2 v2.0.7 // indirect\n\tgithub.com/hashicorp/hcl v1.0.1-vault-7 // indirect\n\tgithub.com/hashicorp/hcp-sdk-go v0.138.0 // indirect\n\tgithub.com/hashicorp/mdns v1.0.4 // indirect\n\tgithub.com/hashicorp/raft v1.7.3 // indirect\n\tgithub.com/hashicorp/raft-autopilot v0.3.0 // indirect\n\tgithub.com/hashicorp/raft-boltdb/v2 v2.3.0 // indirect\n\tgithub.com/hashicorp/raft-snapshot v1.0.4 // indirect\n\tgithub.com/hashicorp/raft-wal v0.4.0 // indirect\n\tgithub.com/hashicorp/vault-plugin-secrets-kv v0.25.0 // indirect\n\tgithub.com/hashicorp/vault/sdk v0.20.0 // indirect\n\tgithub.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect\n\tgithub.com/hashicorp/yamux v0.1.2 // indirect\n\tgithub.com/huandu/xstrings v1.5.0 // indirect\n\tgithub.com/jackc/chunkreader/v2 v2.0.1 // indirect\n\tgithub.com/jackc/pgconn v1.14.3 // indirect\n\tgithub.com/jackc/pgio v1.0.0 // indirect\n\tgithub.com/jackc/pgpassfile v1.0.0 // indirect\n\tgithub.com/jackc/pgproto3/v2 v2.3.3 // indirect\n\tgithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect\n\tgithub.com/jackc/pgtype v1.14.3 // indirect\n\tgithub.com/jackc/pgx/v4 v4.18.3 // indirect\n\tgithub.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect\n\tgithub.com/jefferai/jsonx v1.0.1 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 // indirect\n\tgithub.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/kelseyhightower/envconfig v1.4.0 // indirect\n\tgithub.com/klauspost/compress v1.18.0 // indirect\n\tgithub.com/kylelemons/godebug v1.1.0 // indirect\n\tgithub.com/labstack/gommon v0.4.2 // indirect\n\tgithub.com/lestrrat-go/backoff/v2 v2.0.8 // indirect\n\tgithub.com/lestrrat-go/blackmagic v1.0.2 // indirect\n\tgithub.com/lestrrat-go/httpcc v1.0.1 // indirect\n\tgithub.com/lestrrat-go/iter v1.0.2 // indirect\n\tgithub.com/lestrrat-go/jwx v1.2.29 // indirect\n\tgithub.com/lestrrat-go/option v1.0.1 // indirect\n\tgithub.com/linode/linodego v0.7.1 // indirect\n\tgithub.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect\n\tgithub.com/mailru/easyjson v0.9.0 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/miekg/dns v1.1.50 // indirect\n\tgithub.com/mitchellh/copystructure v1.2.0 // indirect\n\tgithub.com/mitchellh/go-homedir v1.1.0 // indirect\n\tgithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect\n\tgithub.com/mitchellh/pointerstructure v1.2.1 // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.2 // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect\n\tgithub.com/oklog/run v1.1.0 // indirect\n\tgithub.com/oklog/ulid v1.3.1 // indirect\n\tgithub.com/okta/okta-sdk-golang/v5 v5.0.2 // indirect\n\tgithub.com/onsi/ginkgo/v2 v2.27.2 // indirect\n\tgithub.com/onsi/gomega v1.38.2 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect\n\tgithub.com/oracle/oci-go-sdk/v60 v60.0.0 // indirect\n\tgithub.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect\n\tgithub.com/patrickmn/go-cache v2.1.0+incompatible // indirect\n\tgithub.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e // indirect\n\tgithub.com/pierrec/lz4 v2.6.1+incompatible // indirect\n\tgithub.com/pires/go-proxyproto v0.8.0 // indirect\n\tgithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/posener/complete v1.2.3 // indirect\n\tgithub.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect\n\tgithub.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d // indirect\n\tgithub.com/prometheus/client_golang v1.22.0 // indirect\n\tgithub.com/prometheus/client_model v0.6.1 // indirect\n\tgithub.com/prometheus/common v0.62.0 // indirect\n\tgithub.com/prometheus/procfs v0.15.1 // indirect\n\tgithub.com/rboyer/safeio v0.2.3 // indirect\n\tgithub.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect\n\tgithub.com/robfig/cron/v3 v3.0.1 // indirect\n\tgithub.com/ryanuber/go-glob v1.0.0 // indirect\n\tgithub.com/sasha-s/go-deadlock v0.3.5 // indirect\n\tgithub.com/segmentio/fasthash v1.0.3 // indirect\n\tgithub.com/sethvargo/go-limiter v0.7.1 // indirect\n\tgithub.com/shirou/gopsutil/v3 v3.22.6 // indirect\n\tgithub.com/shopspring/decimal v1.4.0 // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect\n\tgithub.com/sony/gobreaker v0.5.0 // indirect\n\tgithub.com/spf13/cast v1.7.1 // indirect\n\tgithub.com/spf13/pflag v1.0.6 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect\n\tgithub.com/tink-crypto/tink-go/v2 v2.4.0 // indirect\n\tgithub.com/tklauser/go-sysconf v0.3.12 // indirect\n\tgithub.com/tklauser/numcpus v0.6.1 // indirect\n\tgithub.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasttemplate v1.2.2 // indirect\n\tgithub.com/vmware/govmomi v0.18.0 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgithub.com/yusufpapurcu/wmi v1.2.4 // indirect\n\tgo.etcd.io/bbolt v1.4.0 // indirect\n\tgo.mongodb.org/mongo-driver v1.17.4 // indirect\n\tgo.opencensus.io v0.24.0 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect\n\tgo.opentelemetry.io/otel v1.39.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.39.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.39.0 // indirect\n\tgo.uber.org/atomic v1.11.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.2 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect\n\tgolang.org/x/mod v0.33.0 // indirect\n\tgolang.org/x/net v0.51.0 // indirect\n\tgolang.org/x/oauth2 v0.34.0 // indirect\n\tgolang.org/x/sync v0.20.0 // indirect\n\tgolang.org/x/sys v0.42.0 // indirect\n\tgolang.org/x/term v0.41.0 // indirect\n\tgolang.org/x/text v0.35.0 // indirect\n\tgolang.org/x/time v0.13.0 // indirect\n\tgolang.org/x/tools v0.42.0 // indirect\n\tgoogle.golang.org/api v0.251.0 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20251002232023-7c0ddcbb5797 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.10 // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/ini.v1 v1.67.0 // indirect\n\tgopkg.in/resty.v1 v1.12.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tk8s.io/api v0.34.1 // indirect\n\tk8s.io/apimachinery v0.34.1 // indirect\n\tk8s.io/client-go v0.34.1 // indirect\n\tk8s.io/klog/v2 v2.130.1 // indirect\n\tk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect\n\tk8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect\n\tsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=\ncloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c=\ncloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI=\ncloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=\ncloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=\ncloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=\ncloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=\ncloud.google.com/go/cloudsqlconn v1.4.3 h1:/WYFbB1NtMtoMxCbqpzzTFPDkxxlLTPme390KEGaEPc=\ncloud.google.com/go/cloudsqlconn v1.4.3/go.mod h1:QL3tuStVOO70txb3rs4G8j5uMfo5ztZii8K3oGD3VYA=\ncloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=\ncloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=\ncloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=\ncloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=\ncloud.google.com/go/kms v1.23.0 h1:WaqAZsUptyHwOo9II8rFC1Kd2I+yvNsNP2IJ14H2sUw=\ncloud.google.com/go/kms v1.23.0/go.mod h1:rZ5kK0I7Kn9W4erhYVoIRPtpizjunlrfU4fUkumUp8g=\ncloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=\ncloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=\ncloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=\ncloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=\ndario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=\ndario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\nfilippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=\nfilippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=\ngithub.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=\ngithub.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=\ngithub.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0=\ngithub.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk=\ngithub.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=\ngithub.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=\ngithub.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=\ngithub.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk=\ngithub.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=\ngithub.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=\ngithub.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=\ngithub.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=\ngithub.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=\ngithub.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM=\ngithub.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE=\ngithub.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=\ngithub.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 h1:UPeCRD+XY7QlaGQte2EVI2iOcWvUYA2XY8w5T/8v0NQ=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1/go.mod h1:oGV6NlB0cvi1ZbYRR2UN44QHxWFyGk+iylgD0qaMXjA=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0 h1:L7G3dExHBgUxsO3qpTGhk/P2dgnYyW48yn7AO33Tbek=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0/go.mod h1:Ms6gYEy0+A2knfKrwdatsggTXYA2+ICKug8w7STorFw=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=\ngithub.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=\ngithub.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1 h1:cf+OIKbkmMHBaC3u78AXomweqM0oxQSgBXRZf3WH4yM=\ngithub.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1/go.mod h1:ap1dmS6vQKJxSMNiGJcq4QuUQkOynyD93gLw6MDF7ek=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=\ngithub.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=\ngithub.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=\ngithub.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.24 h1:BHZfgGsGwdkHDyZdtQRQk1WeUdW0m2WPAwuHZwUi5i4=\ngithub.com/Azure/go-autorest/autorest/adal v0.9.24/go.mod h1:7T1+g0PYFmACYW5LlG2fcoPiPlFHjClyRGL7dRlP5c8=\ngithub.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk=\ngithub.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg=\ngithub.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg=\ngithub.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc=\ngithub.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=\ngithub.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=\ngithub.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=\ngithub.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=\ngithub.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=\ngithub.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=\ngithub.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=\ngithub.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=\ngithub.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=\ngithub.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=\ngithub.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=\ngithub.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=\ngithub.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=\ngithub.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=\ngithub.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=\ngithub.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=\ngithub.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=\ngithub.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=\ngithub.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=\ngithub.com/Jeffail/gabs/v2 v2.1.0 h1:6dV9GGOjoQgzWTQEltZPXlJdFloxvIq7DwqgxMCbq30=\ngithub.com/Jeffail/gabs/v2 v2.1.0/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI=\ngithub.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=\ngithub.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=\ngithub.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=\ngithub.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=\ngithub.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=\ngithub.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=\ngithub.com/ProtonMail/gopenpgp/v3 v3.2.1 h1:ohRlKL5YwyIkN5kk7uBvijiMsyA57mK0yBEJg9xButU=\ngithub.com/ProtonMail/gopenpgp/v3 v3.2.1/go.mod h1:x7RduTo/0n/2PjTFRoEHApaxye/8PFbhoCquwfYBUGM=\ngithub.com/SAP/go-hdb v1.10.1 h1:c9dGT5xHZNDwPL3NQcRpnNISn3MchwYaGoMZpCAllUs=\ngithub.com/SAP/go-hdb v1.10.1/go.mod h1:vxYDca44L2eRudZv5JAI6T+IygOfxb7vOCFh/Kj0pug=\ngithub.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=\ngithub.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=\ngithub.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/aliyun/alibaba-cloud-sdk-go v1.63.107 h1:qagvUyrgOnBIlVRQWOyCZGVKUIYbMBdGdJ104vBpRFU=\ngithub.com/aliyun/alibaba-cloud-sdk-go v1.63.107/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=\ngithub.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=\ngithub.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=\ngithub.com/apache/arrow-go/v18 v18.4.0 h1:/RvkGqH517iY8bZKc4FD5/kkdwXJGjxf28JIXbJ/oB0=\ngithub.com/apache/arrow-go/v18 v18.4.0/go.mod h1:Aawvwhj8x2jURIzD9Moy72cF0FyJXOpkYpdmGRHcw14=\ngithub.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc=\ngithub.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g=\ngithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=\ngithub.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=\ngithub.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=\ngithub.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=\ngithub.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=\ngithub.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=\ngithub.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=\ngithub.com/aws/aws-sdk-go v1.34.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=\ngithub.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ=\ngithub.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk=\ngithub.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8=\ngithub.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg=\ngithub.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=\ngithub.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.15 h1:I5XjesVMpDZXZEZonVfjI12VNMrYa38LtLnw4NtY5Ss=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.15/go.mod h1:tNIp4JIPonlsgaO5hxO372a6gjhN63aSWl2GVl5QoBQ=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.68 h1:cFb9yjI02/sWHBSYXAtkamjzCuRymvmeFmt0TC0MbYY=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.68/go.mod h1:H6E+jBzyqUu8u0vGaU6POkK3P0NylYEeRZ6ynBpMqIk=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=\ngithub.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.15 h1:7Zwtt/lP3KNRkeZre7soMELMGNoBrutx8nobg1jKWmo=\ngithub.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.15/go.mod h1:436h2adoHb57yd+8W+gYPrrA9U/R/SuAuOO42Ushzhw=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=\ngithub.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=\ngithub.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=\ngithub.com/aws/aws-sdk-go-v2/service/ec2 v1.200.0 h1:3hH6o7Z2WeE1twvz44Aitn6Qz8DZN3Dh5IB4Eh2xq7s=\ngithub.com/aws/aws-sdk-go-v2/service/ec2 v1.200.0/go.mod h1:I76S7jN0nfsYTBtuTgTsJtK2Q8yJVDgrLr5eLN64wMA=\ngithub.com/aws/aws-sdk-go-v2/service/ecs v1.53.8 h1:v1OectQdV/L+KSFSiqK00fXGN8FbaljRfNFysmWB8D0=\ngithub.com/aws/aws-sdk-go-v2/service/ecs v1.53.8/go.mod h1:F0DbgxpvuSvtYun5poG67EHLvci4SgzsMVO6SsPUqKk=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=\ngithub.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 h1:BCG7DCXEXpNCcpwCxg1oi9pkJWH2+eZzTn9MY56MbVw=\ngithub.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=\ngithub.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=\ngithub.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=\ngithub.com/aws/aws-sdk-go-v2/service/s3 v1.80.1 h1:xYEAf/6QHiTZDccKnPMbsMwlau13GsDsTgdue3wmHGw=\ngithub.com/aws/aws-sdk-go-v2/service/s3 v1.80.1/go.mod h1:qbn305Je/IofWBJ4bJz/Q7pDEtnnoInw/dGt71v6rHE=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.20 h1:oIaQ1e17CSKaWmUTu62MtraRWVIosn/iONMuZt0gbqc=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.20/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=\ngithub.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw=\ngithub.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=\ngithub.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA=\ngithub.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\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/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E=\ngithub.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=\ngithub.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=\ngithub.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=\ngithub.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=\ngithub.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=\ngithub.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=\ngithub.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\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/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0 h1:CWU8piLyqoi9qXEUwzOh5KFKGgmSU5ZhktJyYcq6ryQ=\ngithub.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0/go.mod h1:5d8DqS60xkj9k3aXfL3+mXBH0DPYO0FQjcKosxl+b/Q=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=\ngithub.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=\ngithub.com/cloudfoundry-community/go-cfclient v0.0.0-20220930021109-9c4e6c59ccf1 h1:ef0OsiQjSQggHrLFAMDRiu6DfkVSElA5jfG1/Nkyu6c=\ngithub.com/cloudfoundry-community/go-cfclient v0.0.0-20220930021109-9c4e6c59ccf1/go.mod h1:sgaEj3tRn0hwe7GPdEUwxrdOqjBzyjyvyOCGf1OQyZY=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=\ngithub.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=\ngithub.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=\ngithub.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=\ngithub.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=\ngithub.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA=\ngithub.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=\ngithub.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=\ngithub.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=\ngithub.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ=\ngithub.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/couchbase/gocb/v2 v2.11.1 h1:xWDco7Qk/XSvGUjbUWRaXi0V35nsMijJnm4vHXN/rqY=\ngithub.com/couchbase/gocb/v2 v2.11.1/go.mod h1:aSh1Cmd1sPRpYyiBD5iWPehPWaTVF/oYhrtOAITWb/4=\ngithub.com/couchbase/gocbcore/v10 v10.8.1 h1:i4SnH0DH9APGC4GS2vS2m+3u08V7oJwviamOXdgAZOQ=\ngithub.com/couchbase/gocbcore/v10 v10.8.1/go.mod h1:OWKfU9R5Nm5V3QZBtfdZl5qCfgxtxTqOgXiNr4pn9/c=\ngithub.com/couchbase/gocbcoreps v0.1.4 h1:/iZVHMpuEw3lyNz9mIahMQffJOurl/opXyOGads/JbI=\ngithub.com/couchbase/gocbcoreps v0.1.4/go.mod h1:hBFpDNPnRno6HH5cRXExhqXYRmTsFJlFHQx7vztcXPk=\ngithub.com/couchbase/goprotostellar v1.0.2 h1:yoPbAL9sCtcyZ5e/DcU5PRMOEFaJrF9awXYu3VPfGls=\ngithub.com/couchbase/goprotostellar v1.0.2/go.mod h1:5/yqVnZlW2/NSbAWu1hPJCFBEwjxgpe0PFFOlRixnp4=\ngithub.com/couchbaselabs/gocbconnstr/v2 v2.0.0 h1:HU9DlAYYWR69jQnLN6cpg0fh0hxW/8d5hnglCXXjW78=\ngithub.com/couchbaselabs/gocbconnstr/v2 v2.0.0/go.mod h1:o7T431UOfFVHDNvMBUmUxpHnhivwv7BziUao/nMl81E=\ngithub.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=\ngithub.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=\ngithub.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=\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/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=\ngithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=\ngithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=\ngithub.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw=\ngithub.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=\ngithub.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4=\ngithub.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/digitalocean/godo v1.7.5 h1:JOQbAO6QT1GGjor0doT0mXefX2FgUDPOpYh2RaXA+ko=\ngithub.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU=\ngithub.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=\ngithub.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=\ngithub.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=\ngithub.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI=\ngithub.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/docker v28.4.0+incompatible h1:KVC7bz5zJY/4AZe/78BIvCnPsLaC9T/zh72xnlrTTOk=\ngithub.com/docker/docker v28.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=\ngithub.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M=\ngithub.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo=\ngithub.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=\ngithub.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=\ngithub.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=\ngithub.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=\ngithub.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=\ngithub.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=\ngithub.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=\ngithub.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=\ngithub.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=\ngithub.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0=\ngithub.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU=\ngithub.com/gammazero/workerpool v1.1.3 h1:WixN4xzukFoN0XSeXF6puqEqFTl2mECI9S6W44HWy9Q=\ngithub.com/gammazero/workerpool v1.1.3/go.mod h1:wPjyBLDbyKnUn2XwwyD3EEwo9dHutia9/fwNmSHWACc=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=\ngithub.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=\ngithub.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=\ngithub.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=\ngithub.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=\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-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=\ngithub.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo=\ngithub.com/go-ldap/ldif v0.0.0-20250910174327-aa3bc3095c92 h1:Eu8/ko8bvygFvum/PWUg5JrGQuWYNahEph8r3SErkSM=\ngithub.com/go-ldap/ldif v0.0.0-20250910174327-aa3bc3095c92/go.mod h1:F640vUoSS6Qg4nmesnVfHeZSJ0ArdMJ9eb0xB7wcitU=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\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-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=\ngithub.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=\ngithub.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=\ngithub.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=\ngithub.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=\ngithub.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=\ngithub.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=\ngithub.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=\ngithub.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=\ngithub.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=\ngithub.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=\ngithub.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=\ngithub.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=\ngithub.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=\ngithub.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=\ngithub.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=\ngithub.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=\ngithub.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE=\ngithub.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=\ngithub.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\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/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=\ngithub.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=\ngithub.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/gocql/gocql v1.0.0 h1:UnbTERpP72VZ/viKE1Q1gPtmLvyTZTvuAstvSRydw/c=\ngithub.com/gocql/gocql v1.0.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=\ngithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=\ngithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=\ngithub.com/gofrs/flock v0.10.0 h1:SHMXenfaB03KbroETaCMtbBg3Yn29v4w1r+tgy4ff4k=\ngithub.com/gofrs/flock v0.10.0/go.mod h1:FirDy1Ing0mI2+kB6wk+vyyAH+e6xiE+EYA0jnzV9jc=\ngithub.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=\ngithub.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=\ngithub.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=\ngithub.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=\ngithub.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=\ngithub.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=\ngithub.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=\ngithub.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=\ngithub.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=\ngithub.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=\ngithub.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=\ngithub.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=\ngithub.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=\ngithub.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=\ngithub.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/certificate-transparency-go v1.3.2 h1:9ahSNZF2o7SYMaKaXhAumVEzXB2QaayzII9C8rv7v+A=\ngithub.com/google/certificate-transparency-go v1.3.2/go.mod h1:H5FpMUaGa5Ab2+KCYsxg6sELw3Flkl7pGZzWdBoYLXs=\ngithub.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=\ngithub.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=\ngithub.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/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.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\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/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=\ngithub.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=\ngithub.com/google/go-metrics-stackdriver v0.2.0 h1:rbs2sxHAPn2OtUj9JdR/Gij1YKGl0BTVD0augB+HEjE=\ngithub.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0=\ngithub.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=\ngithub.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=\ngithub.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\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/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=\ngithub.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=\ngithub.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=\ngithub.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=\ngithub.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=\ngithub.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=\ngithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=\ngithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=\ngithub.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=\ngithub.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=\ngithub.com/hashicorp/cap v0.11.0 h1:tnMNgIWEdbmyx0fulrlLPNHowsprg34xFWflOEB3t1s=\ngithub.com/hashicorp/cap v0.11.0/go.mod h1:HKbv27kfps+wONFNyNTHpAQmU/DCjjDuB5HF6mFsqPQ=\ngithub.com/hashicorp/cap/ldap v0.0.0-20250911140431-44d01434c285 h1:vwg2CDaWTJJkr+5ivc2KUYx877gPAUEgq5QIPA/bKjw=\ngithub.com/hashicorp/cap/ldap v0.0.0-20250911140431-44d01434c285/go.mod h1:La1zaRmx2oqz79W9SpwQAPMfDUdBxZeoN2IaAQ8D4ow=\ngithub.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU=\ngithub.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=\ngithub.com/hashicorp/consul/api v1.32.1 h1:0+osr/3t/aZNAdJX558crU3PEjVrG4x6715aZHRgceE=\ngithub.com/hashicorp/consul/api v1.32.1/go.mod h1:mXUWLnxftwTmDv4W3lzxYCPD199iNLLUyLfLGFJbtl4=\ngithub.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/consul/sdk v0.16.2 h1:cGX/djeEe9r087ARiKVWwVWCF64J+yW0G6ftZMZYbj0=\ngithub.com/hashicorp/consul/sdk v0.16.2/go.mod h1:onxcZjYVsPx5XMveAC/OtoIsdr32fykB7INFltDoRE8=\ngithub.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A=\ngithub.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=\ngithub.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/eventlogger v0.2.10 h1:Dddth3KVSribGE1rInGToM30tRNblvL0G1OG6N+i2pk=\ngithub.com/hashicorp/eventlogger v0.2.10/go.mod h1:imHMTfJH4qfb8Knh9nZw4iLfL9J1bX6TJKEurSB4t+U=\ngithub.com/hashicorp/go-bexpr v0.1.12 h1:XrdVhmwu+9iYxIUWxsGVG7NQwrhzJZ0vR6nbN5bLgrA=\ngithub.com/hashicorp/go-bexpr v0.1.12/go.mod h1:ACktpcSySkFNpcxWSClFrut7wicd9WzisnvHuw+g9K8=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=\ngithub.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=\ngithub.com/hashicorp/go-discover v1.1.1-0.20250922102917-55e5010ad859 h1:CYvtQfS6WBZdva446zuZEpHxDfI3GTenOM4SCmGWUR8=\ngithub.com/hashicorp/go-discover v1.1.1-0.20250922102917-55e5010ad859/go.mod h1:NsxyJAVM+f1GYWjoAg1dtKU7I39rOWtUjFSm2Xmuvn4=\ngithub.com/hashicorp/go-discover/provider/gce v0.0.0-20241120163552-5eb1507d16b4 h1:ywaDsVo7n5ko12YD8uXjuQ8G2mQhC2mxAc4Kj3WW3GE=\ngithub.com/hashicorp/go-discover/provider/gce v0.0.0-20241120163552-5eb1507d16b4/go.mod h1:yxikfLXA8Y5JA3FcFTR720PfqVEFd0dZY9FBpmcsO54=\ngithub.com/hashicorp/go-gcp-common v0.9.2 h1:hUZ46EdGwlbP+Ttrif6hlcfvtQGzJiS6FUbb649yAOQ=\ngithub.com/hashicorp/go-gcp-common v0.9.2/go.mod h1:STcRASKUYdCtaKbZinoAR/URmkIUGIOTOHUNPrF9xOE=\ngithub.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=\ngithub.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=\ngithub.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=\ngithub.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 h1:kBoJV4Xl5FLtBfnBjDvBxeNSy2IRITSGs73HQsFUEjY=\ngithub.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6/go.mod h1:y+HSOcOGB48PkUxNyLAiCiY6rEENu+E+Ss4LG8QHwf4=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=\ngithub.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.1 h1:KIge4FHZEDb2/xjaWgmBheCTgRL6HV4sgTfDsH876L8=\ngithub.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.1/go.mod h1:aHO1EoFD0kBYLBedqxXgalfFT8lrWfP7kpuSoaqGjH0=\ngithub.com/hashicorp/go-kms-wrapping/v2 v2.0.18 h1:DLfC677GfKEpSAFpEWvl1vXsGpEcSHmbhBaPLrdDQHc=\ngithub.com/hashicorp/go-kms-wrapping/v2 v2.0.18/go.mod h1:t/eaR/mi2mw3klfl1WEAuiLKrlZ/Q8cosmsT+RIPLu0=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.10 h1:am7ai27sEGpfOefHhUShbWAOa6EvkBaiMpB7zZ/PUyo=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.10/go.mod h1:sYX07HI7wMCFe9+FmxMOCwJ7q5CD4aq3VI+KoB8FYZY=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.4 h1:8XgCt3ZDfE0MPBLJsUE4ZnPkFAF4K13Zxqyjx1lA22A=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.4/go.mod h1:Inx0DLGr58Un5TerS8je0SGZwKKihotqaxqoAKHpSmk=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.11 h1:J9zGa9SlcOHT3SQTj0Vv3shHo0anWbs58weURGCgChI=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.11/go.mod h1:iAOCu7/lG5eugg8+k7NVvQt0IpWT8s2Q9wnMtC/guM4=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault/v2 v2.0.14 h1:oK4OQ5EPbx/66dAvitksV+OdrQ86SZEj3B6VSZrbdEY=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault/v2 v2.0.14/go.mod h1:fWxrv9YkAMqtsISde5mcutoMvuiH4kyg1AlDzzmqRh8=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.13 h1:NGBZnF+yPRZ3gjFl69Y2m58/U0iyB2oH9HaznL9tekA=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.13/go.mod h1:4Xb+6d8VPeDcUNuh4toPqJlDpkajeJyIQeg36TtWhKw=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.9 h1:rlKOPHzZ41QeV/H6UIX2wVkPhLzVK+nKhLRIbIAZ0Yc=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.9/go.mod h1:pHJfTvq97FAKCWxIJOHZWQmVfRXmUN6tmgEcgj3nC+M=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.13 h1:UuDeq3nr0e+H9CrZM3dvpDGkWFSJYTtuTqVekn2za2k=\ngithub.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.13/go.mod h1:E2dYgXYNkvKe84PIxD9eJqqhFRA4guCTDweJR4i0gds=\ngithub.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo=\ngithub.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y=\ngithub.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY=\ngithub.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI=\ngithub.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=\ngithub.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=\ngithub.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0=\ngithub.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=\ngithub.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=\ngithub.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg=\ngithub.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0=\ngithub.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4=\ngithub.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU=\ngithub.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=\ngithub.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=\ngithub.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=\ngithub.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=\ngithub.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 h1:I8bynUKMh9I7JdwtW9voJ0xmHvBpxQtLjrMFDYmhOxY=\ngithub.com/hashicorp/go-secure-stdlib/awsutil v0.3.0/go.mod h1:oKHSQs4ivIfZ3fbXGQOop1XuDfdSb8RIsWTGaAanSfg=\ngithub.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng=\ngithub.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=\ngithub.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.1 h1:VaLXp47MqD1Y2K6QVrA9RooQiPyCgAbnfeJg44wKuJk=\ngithub.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.1/go.mod h1:hH8rgXHh9fPSDPerG6WzABHsHF+9ZpLhRI1LPk4JZ8c=\ngithub.com/hashicorp/go-secure-stdlib/fileutil v0.1.0 h1:f2mwVgMJjXuX/+eWD6ZW30+oIRgCofL+XMWknFkB1WM=\ngithub.com/hashicorp/go-secure-stdlib/fileutil v0.1.0/go.mod h1:uwcr2oga9pN5+OkHZyTN5MDk3+1YHOuMukhpnPaQAoI=\ngithub.com/hashicorp/go-secure-stdlib/httputil v0.1.0 h1:0cT/LmCfurGE6/MOq8ig3meKYS32YDh0sTE9g86ANgg=\ngithub.com/hashicorp/go-secure-stdlib/httputil v0.1.0/go.mod h1:Md+jfeLf7CjGjTmgBWzFyc4vznsIb8yEiX7/CGAJvkI=\ngithub.com/hashicorp/go-secure-stdlib/mlock v0.1.3 h1:kH3Rhiht36xhAfhuHyWJDgdXXEx9IIZhDGRk24CDhzg=\ngithub.com/hashicorp/go-secure-stdlib/mlock v0.1.3/go.mod h1:ov1Q0oEDjC3+A4BwsG2YdKltrmEw8sf9Pau4V9JQ4Vo=\ngithub.com/hashicorp/go-secure-stdlib/nonceutil v0.1.0 h1:iJG9Q3iUme12yH+wzBMGYrw/Am4CfX3sDcA8m5OGfhQ=\ngithub.com/hashicorp/go-secure-stdlib/nonceutil v0.1.0/go.mod h1:s28ohJ0kU6tersf0it/WsBCyZSdziPlP+G1FRA3ar28=\ngithub.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=\ngithub.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=\ngithub.com/hashicorp/go-secure-stdlib/password v0.1.4 h1:h8gOB6qDRlOMvoMHOqtf4oTdB+goC/hWX0+TXA+VltI=\ngithub.com/hashicorp/go-secure-stdlib/password v0.1.4/go.mod h1:DeLx56RZZdmwX8Q94fVQUetkXv6zVBfDtGAPJDh69AU=\ngithub.com/hashicorp/go-secure-stdlib/permitpool v1.0.0 h1:U6y5MXGiDVOOtkWJ6o/tu1TxABnI0yKTQWJr7z6BpNk=\ngithub.com/hashicorp/go-secure-stdlib/permitpool v1.0.0/go.mod h1:ecDb3o+8D4xtP0nTCufJaAVawHavy5M2eZ64Nq/8/LM=\ngithub.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2 h1:gCNiM4T5xEc4IpT8vM50CIO+AtElr5kO9l2Rxbq+Sz8=\ngithub.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2/go.mod h1:6ZM4ZdwClyAsiU2uDBmRHCvq0If/03BMbF9U+U7G5pA=\ngithub.com/hashicorp/go-secure-stdlib/regexp v1.0.0 h1:08mz6j5MsCG9sf8tvC8Lhboe/ZMiNg41IPSh6unK5T4=\ngithub.com/hashicorp/go-secure-stdlib/regexp v1.0.0/go.mod h1:n/Gj3sYIEEOYds8uKS55bFf7XiYvWN4e+d+UOA7r/YU=\ngithub.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 h1:SMGUnbpAcat8rIKHkBPjfv81yC46a8eCNZ2hsR2l1EI=\ngithub.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1/go.mod h1:Ch/bf00Qnx77MZd49JRgHYqHQjtEmTgGU2faufpVZb0=\ngithub.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=\ngithub.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=\ngithub.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3 h1:xbrxd0U9XQW8qL1BAz2XrAjAF/P2vcqUTAues9c24B8=\ngithub.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3/go.mod h1:LWq2Sy8UoKKuK4lFuCNWSjJj57MhNNf2zzBWMtkAIX4=\ngithub.com/hashicorp/go-slug v0.16.7 h1:sBW8y1sX+JKOZKu9a+DQZuWDVaX+U9KFnk6+VDQvKcw=\ngithub.com/hashicorp/go-slug v0.16.7/go.mod h1:X5fm++dL59cDOX8j48CqHr4KARTQau7isGh0ZVxJB5I=\ngithub.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=\ngithub.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=\ngithub.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-tfe v1.93.0 h1:hJubwn1xNCo1iBO66iQkjyC+skR61cK1AQUj4O9vvuI=\ngithub.com/hashicorp/go-tfe v1.93.0/go.mod h1:QwqgCD5seztgp76CP7F0POJPflQNSqjIvBpVohg9X50=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=\ngithub.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=\ngithub.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=\ngithub.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=\ngithub.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=\ngithub.com/hashicorp/hcp-sdk-go v0.138.0 h1:AYK2N28zJjHlqzkYVAamwtikTpIMNdl+5ZyBBuuQGDY=\ngithub.com/hashicorp/hcp-sdk-go v0.138.0/go.mod h1:1HCJgX11KAIccfyKxwqFOMNbCRMaSvCB68EkOnOTRUM=\ngithub.com/hashicorp/jsonapi v1.4.3-0.20250220162346-81a76b606f3e h1:xwy/1T0cxHWaLx2MM0g4BlaQc1BXn/9835mPrBqwSPU=\ngithub.com/hashicorp/jsonapi v1.4.3-0.20250220162346-81a76b606f3e/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM=\ngithub.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ=\ngithub.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=\ngithub.com/hashicorp/nomad/api v0.0.0-20240213164230-c364cb57298d h1:nvfutImOr3GgkMSMjfNdTil9e54vtyQxxyHZ+NHII3Y=\ngithub.com/hashicorp/nomad/api v0.0.0-20240213164230-c364cb57298d/go.mod h1:ijDwa6o1uG1jFSq6kERiX2PamKGpZzTmo0XOFNeFZgw=\ngithub.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=\ngithub.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=\ngithub.com/hashicorp/raft v1.7.3 h1:DxpEqZJysHN0wK+fviai5mFcSYsCkNpFUl1xpAW8Rbo=\ngithub.com/hashicorp/raft v1.7.3/go.mod h1:DfvCGFxpAUPE0L4Uc8JLlTPtc3GzSbdH0MTJCLgnmJQ=\ngithub.com/hashicorp/raft-autopilot v0.3.0 h1:KhXCecBFqAMpC0i77qVfuYd937cl2dNatSA/sSNs+2s=\ngithub.com/hashicorp/raft-autopilot v0.3.0/go.mod h1:pUBzcE8bXIm/NcFZ/xKz7O3aNOU/4T4Zkv11YqdxpUc=\ngithub.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=\ngithub.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702 h1:RLKEcCuKcZ+qp2VlaaZsYZfLOmIiuJNpEi48Rl8u9cQ=\ngithub.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702/go.mod h1:nTakvJ4XYq45UXtn0DbwR4aU9ZdjlnIenpbs6Cd+FM0=\ngithub.com/hashicorp/raft-boltdb/v2 v2.3.0 h1:fPpQR1iGEVYjZ2OELvUHX600VAK5qmdnDEv3eXOwZUA=\ngithub.com/hashicorp/raft-boltdb/v2 v2.3.0/go.mod h1:YHukhB04ChJsLHLJEUD6vjFyLX2L3dsX3wPBZcX4tmc=\ngithub.com/hashicorp/raft-snapshot v1.0.4 h1:EuDuayAJPdiDmVk1ygTDnG2zDzrs0/6/yBuma1IYSow=\ngithub.com/hashicorp/raft-snapshot v1.0.4/go.mod h1:5sL9eUn72lH5DzsFIJ9jaysITbHksSSszImWSOTC8Ic=\ngithub.com/hashicorp/raft-wal v0.4.0 h1:oHCQLPa3gBTrfuBVHaDg2b/TVXpU0RIyeH/mU9ovk3Y=\ngithub.com/hashicorp/raft-wal v0.4.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE=\ngithub.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=\ngithub.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=\ngithub.com/hashicorp/vault v1.21.2 h1:t6/vAAhgGvKukkIAQBUPenvfLiJ5oUm8CmOMa6tgUYQ=\ngithub.com/hashicorp/vault v1.21.2/go.mod h1:mjP/x4G0ueDLcOetPYypOmAIn+ofFDcahAX4LXaTH9c=\ngithub.com/hashicorp/vault-plugin-auth-alicloud v0.22.0 h1:lukm7hwIDQfDyG6IyvBu2tcT6j2bRuyyo22sWqH4w50=\ngithub.com/hashicorp/vault-plugin-auth-alicloud v0.22.0/go.mod h1:QCuzE/JFqigUf4DyyWyYKq6bvf2dmRKUW340CTy+HZ0=\ngithub.com/hashicorp/vault-plugin-auth-azure v0.22.0 h1:xvRYu2Xirn6gl/GvhPei7DJgJDDTEvsxxEHkBxuj/Iw=\ngithub.com/hashicorp/vault-plugin-auth-azure v0.22.0/go.mod h1:G/wFIXYlPQDXusYD54tlZIb3CDk2cy9OB9hUXyWkqf4=\ngithub.com/hashicorp/vault-plugin-auth-cf v0.22.0 h1:DTK733vsB2lBVwSLxra3/IuhlGdkQVW11T/q0qdXyis=\ngithub.com/hashicorp/vault-plugin-auth-cf v0.22.0/go.mod h1:qToMQoW7dX1egtJwEHd21I/7pgzg+DBEwRAytd+Pgtc=\ngithub.com/hashicorp/vault-plugin-auth-gcp v0.22.0 h1:c5LEJmHNV6VzbKTM9nn05uGLhu0VRnIsacCshj0AJ8M=\ngithub.com/hashicorp/vault-plugin-auth-gcp v0.22.0/go.mod h1:6WhVeAZUu+67H4tkXsnFoUU3+UaBFLlE6ffUHDkVM0o=\ngithub.com/hashicorp/vault-plugin-auth-jwt v0.25.0 h1:YdrZ+fGutoaaF/Hiw3+xtmcRalmqGH8sXRKIrkr5dsk=\ngithub.com/hashicorp/vault-plugin-auth-jwt v0.25.0/go.mod h1:HhfLJxvpYt10mrZoBTa+ToioN9HGOZbWYSR1UHqTMrs=\ngithub.com/hashicorp/vault-plugin-auth-kerberos v0.16.0 h1:bZpmQS26TorpeensFerDPM7z+NgZjrRj9IbdGRdjaLM=\ngithub.com/hashicorp/vault-plugin-auth-kerberos v0.16.0/go.mod h1:O6b92icQx0LGuknyVEVP/XgYjoYDNiTR9cJ1pEUuwjw=\ngithub.com/hashicorp/vault-plugin-auth-kubernetes v0.23.1 h1:9SW3Qu08RR9Tyn2K0wU4rcjQtYf1ykgPcyFgWs/TqTY=\ngithub.com/hashicorp/vault-plugin-auth-kubernetes v0.23.1/go.mod h1:Uzb/uPdIKqXmq3xo4NNT2+5HgXlxNfuDKwU2EqzwD8s=\ngithub.com/hashicorp/vault-plugin-auth-oci v0.20.1 h1:EZ987+/S95JJoh+D8DNvHb3kBFMsBmmEop+MFWUWhZw=\ngithub.com/hashicorp/vault-plugin-auth-oci v0.20.1/go.mod h1:+xx8inhi7pg39SP0JlxSgaXWxNMWmB4iNbjFfMac3bs=\ngithub.com/hashicorp/vault-plugin-database-couchbase v0.15.0 h1:6gLCOwwErqMgo9pJvsrOkg4tL7HmE95r3JVc14hSFSY=\ngithub.com/hashicorp/vault-plugin-database-couchbase v0.15.0/go.mod h1:KpGJp2QKCpMFhzMTdovoZFtx56Q7yQ8oO4fg+UuMGrI=\ngithub.com/hashicorp/vault-plugin-database-elasticsearch v0.19.0 h1:8vbxtLgvTEyve6mJt6aLuaje7NW3aEkJMjf20QFB0gs=\ngithub.com/hashicorp/vault-plugin-database-elasticsearch v0.19.0/go.mod h1:K0W2sRQPX2T0Rv4eRba5d048nDF1/XcjaI/IJ5EHD3I=\ngithub.com/hashicorp/vault-plugin-database-mongodbatlas v0.16.0 h1:/eF3lUTELNWU6NoHDLDdv0waibHHG281q7+RbwujGNU=\ngithub.com/hashicorp/vault-plugin-database-mongodbatlas v0.16.0/go.mod h1:er08o2cVwPpYbcOwlWDX7IdXzPs3gcgCiuujJ8jy6po=\ngithub.com/hashicorp/vault-plugin-database-redis v0.7.0 h1:bX7TjGaGehMEWdimbjoIfsXTSQK/uMSsUwwjjvatcDQ=\ngithub.com/hashicorp/vault-plugin-database-redis v0.7.0/go.mod h1:Hus6qqbgqFxIAJQexX7t/NefW80b0nMXt9BmMQgSnvo=\ngithub.com/hashicorp/vault-plugin-database-redis-elasticache v0.8.0 h1:WJArG0q8XOmnCqKXON/5i/8d0lOI/bsBSc0vSejpIOo=\ngithub.com/hashicorp/vault-plugin-database-redis-elasticache v0.8.0/go.mod h1:3NEQYiGDheoN2g73xAWzgHuzsIle+RnIr7qPO6hF+co=\ngithub.com/hashicorp/vault-plugin-database-snowflake v0.15.0 h1:j1A0JaZvY1aQyxjPQTsW7KA8oS1wCtAe8/m/n1lOCBE=\ngithub.com/hashicorp/vault-plugin-database-snowflake v0.15.0/go.mod h1:Y1QSlXgGj5j7cYYG6I/h7P4kJPkW1pT9AoTuEH4Il4Y=\ngithub.com/hashicorp/vault-plugin-secrets-ad v0.21.0 h1:hQ3NmPvlfqjUJOFVPsmLKtVjJLgTGC6svkL2CGoo8zs=\ngithub.com/hashicorp/vault-plugin-secrets-ad v0.21.0/go.mod h1:+DVIGigIqw63QjP3/3tHQnB8EYzc1YfhKsTr+WJGZns=\ngithub.com/hashicorp/vault-plugin-secrets-alicloud v0.21.0 h1:ywGi5dHIFAqpuC8NiDxSfKIP0WkomRIZXgG40+eY3Hg=\ngithub.com/hashicorp/vault-plugin-secrets-alicloud v0.21.0/go.mod h1:4g79uHg6DPsa4k6B6iEUK5vYDIAnkOlJJI5kZK1BAcE=\ngithub.com/hashicorp/vault-plugin-secrets-azure v0.23.0 h1:oetvEJqXP+2jGM9CfT/LjpJyuViNKdjPKFbDIkRdaPo=\ngithub.com/hashicorp/vault-plugin-secrets-azure v0.23.0/go.mod h1:QkmR0rnexjc330oUzoiuXFsA6OnxmI56h4jnDb1PKbY=\ngithub.com/hashicorp/vault-plugin-secrets-gcp v0.23.0 h1:hqZlxS4Ya0DBt+FutW6z6tSEdnwHFusY49x7TLKVrAw=\ngithub.com/hashicorp/vault-plugin-secrets-gcp v0.23.0/go.mod h1:OmRHszxWAV9MTwFeQKDQmrpRw9q+RMp1vohCuhkkr1k=\ngithub.com/hashicorp/vault-plugin-secrets-gcpkms v0.22.0 h1:z4loMjsAyTKiT4mYMmPNyVxQpetj9vD6dGEtTRxOV5A=\ngithub.com/hashicorp/vault-plugin-secrets-gcpkms v0.22.0/go.mod h1:pPaA7AchrBQ2i62x33vPRTux7wKZiKSfU6jayuv9hLI=\ngithub.com/hashicorp/vault-plugin-secrets-kubernetes v0.12.0 h1:xYuLtQHKvaZtmr6JXPqC4tH9n7zXoOWnpXrHcVTLqbo=\ngithub.com/hashicorp/vault-plugin-secrets-kubernetes v0.12.0/go.mod h1:k8eNkBBNHJwWKVo+WP/iM5xrlvPt65oPNPGwbgQQf14=\ngithub.com/hashicorp/vault-plugin-secrets-kv v0.25.0 h1:5Xx8Hub0nAoFLIHZ4d9tMpPG+MACHXLzed5i7hViKTk=\ngithub.com/hashicorp/vault-plugin-secrets-kv v0.25.0/go.mod h1:Xy3wQwAJxhVZweR2DXBrEgk1erkWKNrhYcuD4Gy4ACo=\ngithub.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.16.0 h1:5/nin7vaRD0GyTCcXtX5cKa5JBuCAAs4e9zbmNbvTPY=\ngithub.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.16.0/go.mod h1:1qO/1BrVkvKSuQm8cOtwLKN27TE0uu5PXxYRrTnpf2s=\ngithub.com/hashicorp/vault-plugin-secrets-openldap v0.17.0 h1:GpgYcuBL66zzFLkf143Q3zFr//BF/4jX/EXXy9wDUOM=\ngithub.com/hashicorp/vault-plugin-secrets-openldap v0.17.0/go.mod h1:UPWSw0hYY37sC4MeeoG9G8jN88DYi3L4MeJjRauhaBI=\ngithub.com/hashicorp/vault-plugin-secrets-terraform v0.13.0 h1:Rhahoi3L1dnZjNqlbUh1f59DMdmfdhsfBvaaX1vjejY=\ngithub.com/hashicorp/vault-plugin-secrets-terraform v0.13.0/go.mod h1:N1fdq0KpTbK/S4Yc4I04JqJ64+mkya4SZ+ychIYd3E4=\ngithub.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=\ngithub.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=\ngithub.com/hashicorp/vault/sdk v0.20.0 h1:a4ulj2gICzw/qH0A4+6o36qAHxkUdcmgpMaSSjqE3dc=\ngithub.com/hashicorp/vault/sdk v0.20.0/go.mod h1:xEjAt/n/2lHBAkYiRPRmvf1d5B6HlisPh2pELlRCosk=\ngithub.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw=\ngithub.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo=\ngithub.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=\ngithub.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=\ngithub.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=\ngithub.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig=\ngithub.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=\ngithub.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=\ngithub.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=\ngithub.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=\ngithub.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=\ngithub.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=\ngithub.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=\ngithub.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=\ngithub.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=\ngithub.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=\ngithub.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=\ngithub.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=\ngithub.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=\ngithub.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=\ngithub.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=\ngithub.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=\ngithub.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=\ngithub.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=\ngithub.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=\ngithub.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=\ngithub.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=\ngithub.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=\ngithub.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=\ngithub.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=\ngithub.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=\ngithub.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=\ngithub.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=\ngithub.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=\ngithub.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=\ngithub.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=\ngithub.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=\ngithub.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=\ngithub.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=\ngithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=\ngithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=\ngithub.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=\ngithub.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=\ngithub.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=\ngithub.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=\ngithub.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=\ngithub.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus=\ngithub.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=\ngithub.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=\ngithub.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=\ngithub.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=\ngithub.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=\ngithub.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=\ngithub.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=\ngithub.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=\ngithub.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=\ngithub.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=\ngithub.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=\ngithub.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=\ngithub.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=\ngithub.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=\ngithub.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=\ngithub.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=\ngithub.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=\ngithub.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=\ngithub.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=\ngithub.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=\ngithub.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=\ngithub.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=\ngithub.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=\ngithub.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=\ngithub.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=\ngithub.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=\ngithub.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=\ngithub.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2 h1:mex1izRBCD+7WjieGgRdy7e651vD/lvB1bD9vNE/3K4=\ngithub.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2/go.mod h1:xkfESuHriIekR+4RoV+fu91j/CfnYM29Zi2tMFw5iD4=\ngithub.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f h1:E87tDTVS5W65euzixn7clSzK66puSt1H4I5SC0EmHH4=\ngithub.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f/go.mod h1:3J2qVK16Lq8V+wfiL2lPeDZ7UWMxk5LemerHa1p6N00=\ngithub.com/jefferai/jsonx v1.0.1 h1:GvWkLWihoLqDG0BSP45TUQJH9qsINX50PVrFULgpc/I=\ngithub.com/jefferai/jsonx v1.0.1/go.mod h1:yFo3l2fcm7cZVHGq3HKLXE+Pd4RWuRjNBDHksM7XekQ=\ngithub.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=\ngithub.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=\ngithub.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY=\ngithub.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 h1:hgVxRoDDPtQE68PT4LFvNlPz2nBKd3OMlGKIQ69OmR4=\ngithub.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531/go.mod h1:fqTUQpVYBvhCNIsMXGl2GE9q6z94DIP6NtFKXCSTVbg=\ngithub.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d h1:J8tJzRyiddAFF65YVgxli+TyWBi0f79Sld6rJP6CBcY=\ngithub.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d/go.mod h1:b+Q3v8Yrg5o15d71PSUraUzYb+jWl6wQMSBXSGS/hv0=\ngithub.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago=\ngithub.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=\ngithub.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=\ngithub.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=\ngithub.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4=\ngithub.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=\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.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=\ngithub.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\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/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=\ngithub.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=\ngithub.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=\ngithub.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=\ngithub.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=\ngithub.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=\ngithub.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=\ngithub.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=\ngithub.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=\ngithub.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=\ngithub.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=\ngithub.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=\ngithub.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ=\ngithub.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8=\ngithub.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=\ngithub.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=\ngithub.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=\ngithub.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=\ngithub.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE=\ngithub.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY=\ngithub.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=\ngithub.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=\ngithub.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=\ngithub.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\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/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mediocregopher/radix/v4 v4.1.4 h1:Uze6DEbEAvL+VHXUEu/EDBTkUk5CLct5h3nVSGpc6Ts=\ngithub.com/mediocregopher/radix/v4 v4.1.4/go.mod h1:ajchozX/6ELmydxWeWM6xCFHVpZ4+67LXHOTOVR0nCE=\ngithub.com/michaelklishin/rabbit-hole/v2 v2.12.0 h1:946p6jOYFcVJdtBBX8MwXvuBkpPjwm1Nm2Qg8oX+uFk=\ngithub.com/michaelklishin/rabbit-hole/v2 v2.12.0/go.mod h1:AN/3zyz7d++OHf+4WUo/LR0+Q5nlPHMaXasIsG/mPY0=\ngithub.com/microsoft/go-mssqldb v1.5.0 h1:CgENxkwtOBNj3Jg6T1X209y2blCfTTcwuOlznd2k9fk=\ngithub.com/microsoft/go-mssqldb v1.5.0/go.mod h1:lmWsjHD8XX/Txr0f8ZqgbEZSC+BZjmEQy/Ms+rLrvho=\ngithub.com/microsoft/kiota-abstractions-go v1.9.3 h1:cqhbqro+VynJ7kObmo7850h3WN2SbvoyhypPn8uJ1SE=\ngithub.com/microsoft/kiota-abstractions-go v1.9.3/go.mod h1:f06pl3qSyvUHEfVNkiRpXPkafx7khZqQEb71hN/pmuU=\ngithub.com/microsoft/kiota-authentication-azure-go v1.3.1 h1:AGta92S6IL1E6ZMDb8YYB7NVNTIFUakbtLKUdY5RTuw=\ngithub.com/microsoft/kiota-authentication-azure-go v1.3.1/go.mod h1:26zylt2/KfKwEWZSnwHaMxaArpbyN/CuzkbotdYXF0g=\ngithub.com/microsoft/kiota-http-go v1.5.4 h1:wSUmL1J+bTQlAWHjbRkSwr+SPAkMVYeYxxB85Zw0KFs=\ngithub.com/microsoft/kiota-http-go v1.5.4/go.mod h1:L+5Ri+SzwELnUcNA0cpbFKp/pBbvypLh3Cd1PR6sjx0=\ngithub.com/microsoft/kiota-serialization-form-go v1.1.2 h1:SD6MATqNw+Dc5beILlsb/D87C36HKC/Zw7l+N9+HY2A=\ngithub.com/microsoft/kiota-serialization-form-go v1.1.2/go.mod h1:m4tY2JT42jAZmgbqFwPy3zGDF+NPJACuyzmjNXeuHio=\ngithub.com/microsoft/kiota-serialization-json-go v1.1.2 h1:eJrPWeQ665nbjO0gsHWJ0Bw6V/ZHHU1OfFPaYfRG39k=\ngithub.com/microsoft/kiota-serialization-json-go v1.1.2/go.mod h1:deaGt7fjZarywyp7TOTiRsjfYiyWxwJJPQZytXwYQn8=\ngithub.com/microsoft/kiota-serialization-multipart-go v1.1.2 h1:1pUyA1QgIeKslQwbk7/ox1TehjlCUUT3r1f8cNlkvn4=\ngithub.com/microsoft/kiota-serialization-multipart-go v1.1.2/go.mod h1:j2K7ZyYErloDu7Kuuk993DsvfoP7LPWvAo7rfDpdPio=\ngithub.com/microsoft/kiota-serialization-text-go v1.1.2 h1:7OfKFlzdjpPygca/+OtqafkEqCWR7+94efUFGC28cLw=\ngithub.com/microsoft/kiota-serialization-text-go v1.1.2/go.mod h1:QNTcswkBPFY3QVBFmzfk00UMNViKQtV0AQKCrRw5ibM=\ngithub.com/microsoftgraph/msgraph-sdk-go v1.86.0 h1:kZSIJuRoP9BUD8xsWL6sk82ThsGhZvDonO8waKH5emU=\ngithub.com/microsoftgraph/msgraph-sdk-go v1.86.0/go.mod h1:h2fx0PGMpIfVX8u5nWTVXmTKTYzIR/uOwZQnX4ixwcM=\ngithub.com/microsoftgraph/msgraph-sdk-go-core v1.4.0 h1:0SrIoFl7TQnMRrsi5TFaeNe0q8KO5lRzRp4GSCCL2So=\ngithub.com/microsoftgraph/msgraph-sdk-go-core v1.4.0/go.mod h1:A1iXs+vjsRjzANxF6UeKv2ACExG7fqTwHHbwh1FL+EE=\ngithub.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=\ngithub.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=\ngithub.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=\ngithub.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE=\ngithub.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ=\ngithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=\ngithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=\ngithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=\ngithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=\ngithub.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=\ngithub.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=\ngithub.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=\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/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE=\ngithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw=\ngithub.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=\ngithub.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=\ngithub.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=\ngithub.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=\ngithub.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=\ngithub.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=\ngithub.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=\ngithub.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=\ngithub.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=\ngithub.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=\ngithub.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=\ngithub.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=\ngithub.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=\ngithub.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=\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.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=\ngithub.com/mongodb-forks/digest v1.1.0 h1:7eUdsR1BtqLv0mdNm4OXs6ddWvR4X2/OsLwdKksrOoc=\ngithub.com/mongodb-forks/digest v1.1.0/go.mod h1:rb+EX8zotClD5Dj4NdgxnJXG9nwrlx3NWKJ8xttz1Dg=\ngithub.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=\ngithub.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=\ngithub.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=\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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s=\ngithub.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=\ngithub.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=\ngithub.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/okta/okta-sdk-golang/v5 v5.0.2 h1:eecvycE/XDX56IWTsOVhqfj5txCgqryTXzKy7wKEq78=\ngithub.com/okta/okta-sdk-golang/v5 v5.0.2/go.mod h1:T/vmECtJX33YPZSVD+sorebd8LLhe38Bi/VrFTjgVX0=\ngithub.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=\ngithub.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=\ngithub.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=\ngithub.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/runc v1.2.6 h1:P7Hqg40bsMvQGCS4S7DJYhUZOISMLJOB2iGX5COWiPk=\ngithub.com/opencontainers/runc v1.2.6/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=\ngithub.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=\ngithub.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=\ngithub.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=\ngithub.com/oracle/oci-go-sdk/v60 v60.0.0 h1:EJAWjEi4SY5Raha6iUzq4LTQ0uM5YFw/wat/L1ehIEM=\ngithub.com/oracle/oci-go-sdk/v60 v60.0.0/go.mod h1:krz+2gkSzlSL/L4PvP0Z9pZpag9HYLNtsMd1PmxlA2w=\ngithub.com/oracle/oci-go-sdk/v65 v65.101.1 h1:ZsrZxvffhaB/RqEPmp5zoCS5KCQU1yY8m9B4KXc1404=\ngithub.com/oracle/oci-go-sdk/v65 v65.101.1/go.mod h1:oB8jFGVc/7/zJ+DbleE8MzGHjhs2ioCz5stRTdZdIcY=\ngithub.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=\ngithub.com/ory/dockertest/v3 v3.12.0 h1:3oV9d0sDzlSQfHtIaB5k6ghUCVMVLpAY8hwrqoCyRCw=\ngithub.com/ory/dockertest/v3 v3.12.0/go.mod h1:aKNDTva3cp8dwOWwb9cWuX84aH5akkxXRvO7KCwWVjE=\ngithub.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE=\ngithub.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M=\ngithub.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e h1:D0bJD+4O3G4izvrQUmzCL80zazlN7EwJ0PPDhpJWC/I=\ngithub.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=\ngithub.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=\ngithub.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=\ngithub.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0=\ngithub.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\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/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=\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/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=\ngithub.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=\ngithub.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=\ngithub.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=\ngithub.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d h1:PinQItctnaL2LtkaSM678+ZLLy5TajwOeXzWvYC7tII=\ngithub.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\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.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=\ngithub.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=\ngithub.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\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/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/rboyer/safeio v0.2.3 h1:gUybicx1kp8nuM4vO0GA5xTBX58/OBd8MQuErBfDxP8=\ngithub.com/rboyer/safeio v0.2.3/go.mod h1:d7RMmt7utQBJZ4B7f0H/cU/EdZibQAU1Y8NWepK2dS8=\ngithub.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o=\ngithub.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU=\ngithub.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=\ngithub.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\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.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=\ngithub.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=\ngithub.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=\ngithub.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=\ngithub.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=\ngithub.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=\ngithub.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=\ngithub.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=\ngithub.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac=\ngithub.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=\ngithub.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=\ngithub.com/sethvargo/go-limiter v0.7.1 h1:wWNhTj0pxjyJ7wuJHpRJpYwJn+bUnjYfw2a85eu5w9U=\ngithub.com/sethvargo/go-limiter v0.7.1/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=\ngithub.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=\ngithub.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=\ngithub.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=\ngithub.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=\ngithub.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=\ngithub.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/snowflakedb/gosnowflake v1.17.0 h1:be50vC0buiOitvneyRHiqNkvPMcunGD3EcTnL2zYATg=\ngithub.com/snowflakedb/gosnowflake v1.17.0/go.mod h1:TaHvQGh9MA2lopZZMm1AvvENDfwcnKtuskIr1e6Fpic=\ngithub.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic=\ngithub.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=\ngithub.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg=\ngithub.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=\ngithub.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=\ngithub.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=\ngithub.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=\ngithub.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=\ngithub.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 h1:7hth9376EoQEd1hH4lAp3vnaLP2UMyxuMMghLKzDHyU=\ngithub.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=\ngithub.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/tencentcloud/tencentcloud-sdk-go v1.0.162 h1:8fDzz4GuVg4skjY2B0nMN7h6uN61EDVkuLyI2+qGHhI=\ngithub.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI=\ngithub.com/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs=\ngithub.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao=\ngithub.com/tink-crypto/tink-go/v2 v2.4.0 h1:8VPZeZI4EeZ8P/vB6SIkhlStrJfivTJn+cQ4dtyHNh0=\ngithub.com/tink-crypto/tink-go/v2 v2.4.0/go.mod h1:l//evrF2Y3MjdbpNDNGnKgCpo5zSmvUvnQ4MU+yE2sw=\ngithub.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=\ngithub.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=\ngithub.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=\ngithub.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=\ngithub.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=\ngithub.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=\ngithub.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=\ngithub.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=\ngithub.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=\ngithub.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=\ngithub.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=\ngithub.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=\ngithub.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=\ngithub.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=\ngithub.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo=\ngithub.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngithub.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=\ngithub.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=\ngithub.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=\ngithub.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=\ngithub.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=\ngithub.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=\ngithub.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=\ngithub.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngithub.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=\ngithub.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngithub.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=\ngithub.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=\ngithub.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=\ngo.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=\ngo.mongodb.org/atlas v0.38.0 h1:zfwymq20GqivGwxPZfypfUDry+WwMGVui97z1d8V4bU=\ngo.mongodb.org/atlas v0.38.0/go.mod h1:DJYtM+vsEpPEMSkQzJnFHrT0sP7ev6cseZc/GGjJYG8=\ngo.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=\ngo.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\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/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=\ngo.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=\ngo.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8=\ngo.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=\ngo.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=\ngo.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=\ngo.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=\ngo.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=\ngo.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=\ngo.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=\ngo.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=\ngo.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=\ngo.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=\ngo.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=\ngo.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=\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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=\ngo.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=\ngo.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=\ngo.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=\ngo.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=\ngo.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=\ngolang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=\ngolang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=\ngolang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=\ngolang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=\ngolang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=\ngolang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=\ngolang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=\ngolang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=\ngolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=\ngolang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=\ngolang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=\ngolang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=\ngolang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=\ngolang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=\ngolang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=\ngolang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0=\ngolang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548=\ngolang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=\ngolang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=\ngolang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=\ngolang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=\ngolang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=\ngolang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=\ngolang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=\ngolang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=\ngolang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\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=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=\ngonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=\ngonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=\ngonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=\ngoogle.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.251.0 h1:6lea5nHRT8RUmpy9kkC2PJYnhnDAB13LqrLSVQlMIE8=\ngoogle.golang.org/api v0.251.0/go.mod h1:Rwy0lPf/TD7+T2VhYcffCHhyyInyuxGjICxdfLqT7KI=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20251002232023-7c0ddcbb5797 h1:06qNPeHxbfl+OJluwQ2zOiTP6di3mvADTHnMYQuOKDQ=\ngoogle.golang.org/genproto v0.0.0-20251002232023-7c0ddcbb5797/go.mod h1:OqVwZqqGV3h7k+YCVWXoTtwC2cs55RnDEUVMMadhxrc=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=\ngoogle.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=\ngopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=\ngopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=\ngopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=\ngopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=\ngopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=\ngotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nk8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=\nk8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=\nk8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=\nk8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=\nk8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=\nk8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=\nk8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=\nk8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\nlayeh.com/radius v0.0.0-20231213012653-1006025d24f8 h1:orYXpi6BJZdvgytfHH4ybOe4wHnLbbS71Cmd8mWdZjs=\nlayeh.com/radius v0.0.0-20231213012653-1006025d24f8/go.mod h1:QRf+8aRqXc019kHkpcs/CTgyWXFzf+bxlsyuo2nAl1o=\nrsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=\nsigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=\nsigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "internal/config.go",
    "content": "// Package internal contains the core business logic for the sup3rS3cretMes5age application,\n// including configuration management, HTTP handlers, server setup, and Vault integration.\npackage internal\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n)\n\n// conf holds the application configuration settings loaded from environment variables.\n// It includes HTTP/HTTPS binding addresses, TLS configuration, and Vault storage prefix.\ntype conf struct {\n\t// HttpBindingAddress is the HTTP server binding address (e.g., \":8080\").\n\tHttpBindingAddress string\n\t// HttpsBindingAddress is the HTTPS server binding address (e.g., \":443\").\n\tHttpsBindingAddress string\n\t// HttpsRedirectEnabled determines whether HTTP requests should redirect to HTTPS.\n\tHttpsRedirectEnabled bool\n\t// TLSAutoDomain is the domain for automatic Let's Encrypt TLS certificate generation.\n\tTLSAutoDomain string\n\t// TLSCertFilepath is the path to a manual TLS certificate file.\n\tTLSCertFilepath string\n\t// TLSCertKeyFilepath is the path to a manual TLS certificate key file.\n\tTLSCertKeyFilepath string\n\t// VaultPrefix is the Vault storage path prefix (defaults to \"cubbyhole/\").\n\tVaultPrefix string\n\t// AllowedOrigins is the list of allowed CORS origins.\n\tAllowedOrigins []string\n}\n\n// Environment variable names for application configuration.\nconst (\n\t// HttpBindingAddressVarenv is the environment variable for HTTP binding address.\n\tHttpBindingAddressVarenv = \"SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS\"\n\t// HttpsBindingAddressVarenv is the environment variable for HTTPS binding address.\n\tHttpsBindingAddressVarenv = \"SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS\"\n\t// HttpsRedirectEnabledVarenv is the environment variable to enable HTTPS redirect.\n\tHttpsRedirectEnabledVarenv = \"SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED\"\n\t// TLSAutoDomainVarenv is the environment variable for automatic TLS domain.\n\tTLSAutoDomainVarenv = \"SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN\"\n\t// TLSCertFilepathVarenv is the environment variable for manual TLS certificate path.\n\tTLSCertFilepathVarenv = \"SUPERSECRETMESSAGE_TLS_CERT_FILEPATH\"\n\t// TLSCertKeyFilepathVarenv is the environment variable for manual TLS key path.\n\tTLSCertKeyFilepathVarenv = \"SUPERSECRETMESSAGE_TLS_CERT_KEY_FILEPATH\"\n\t// VaultPrefixenv is the environment variable for Vault storage prefix.\n\tVaultPrefixenv = \"SUPERSECRETMESSAGE_VAULT_PREFIX\"\n\t// AllowedOriginsVarenv is the environment variable for allowed CORS origins.\n\tAllowedOriginsVarenv = \"SUPERSECRETMESSAGE_ALLOWED_ORIGINS\"\n)\n\n// LoadConfig loads and validates application configuration from environment variables.\n// It validates TLS configuration mutual exclusivity, ensures required bindings are set,\n// and sets default values where appropriate. Exits with fatal error on invalid configuration.\nfunc LoadConfig() conf {\n\tvar cnf conf\n\n\tcnf.HttpBindingAddress = os.Getenv(HttpBindingAddressVarenv)\n\tcnf.HttpsBindingAddress = os.Getenv(HttpsBindingAddressVarenv)\n\tcnf.HttpsRedirectEnabled = strings.ToLower(os.Getenv(HttpsRedirectEnabledVarenv)) == \"true\"\n\tcnf.TLSAutoDomain = os.Getenv(TLSAutoDomainVarenv)\n\tcnf.TLSCertFilepath = os.Getenv(TLSCertFilepathVarenv)\n\tcnf.TLSCertKeyFilepath = os.Getenv(TLSCertKeyFilepathVarenv)\n\tcnf.VaultPrefix = os.Getenv(VaultPrefixenv)\n\tcnf.AllowedOrigins = strings.Split(os.Getenv(AllowedOriginsVarenv), \",\")\n\n\tif cnf.TLSAutoDomain != \"\" && (cnf.TLSCertFilepath != \"\" || cnf.TLSCertKeyFilepath != \"\") {\n\t\tlog.Fatalf(\"Auto TLS (%s) is mutually exclusive with manual TLS (%s and %s)\", TLSAutoDomainVarenv,\n\t\t\tTLSCertFilepathVarenv, TLSCertKeyFilepathVarenv)\n\t}\n\n\tif (cnf.TLSCertFilepath != \"\" && cnf.TLSCertKeyFilepath == \"\") ||\n\t\t(cnf.TLSCertFilepath == \"\" && cnf.TLSCertKeyFilepath != \"\") {\n\t\tlog.Fatalf(\"Both certificate filepath (%s) and certificate key filepath (%s) must be set when using manual TLS\",\n\t\t\tTLSCertFilepathVarenv, TLSCertKeyFilepathVarenv)\n\t}\n\n\tif cnf.HttpsBindingAddress == \"\" && (cnf.TLSAutoDomain != \"\" || cnf.TLSCertFilepath != \"\") {\n\t\tlog.Fatalf(\"HTTPS binding address (%s) must be set when using either auto TLS (%s) or manual TLS (%s and %s)\",\n\t\t\tHttpsBindingAddressVarenv, TLSAutoDomainVarenv, TLSCertFilepathVarenv, TLSCertKeyFilepathVarenv)\n\t}\n\n\tif cnf.HttpBindingAddress == \"\" && cnf.TLSAutoDomain == \"\" && cnf.TLSCertFilepath == \"\" {\n\t\tlog.Fatalf(\"HTTP binding address (%s) must be set if auto TLS (%s) and manual TLS (%s and %s) are both disabled\",\n\t\t\tHttpBindingAddressVarenv, TLSAutoDomainVarenv, TLSCertFilepathVarenv, TLSCertKeyFilepathVarenv)\n\t}\n\n\tif cnf.HttpsBindingAddress != \"\" && cnf.TLSAutoDomain == \"\" && cnf.TLSCertFilepath == \"\" {\n\t\tlog.Fatalf(\"HTTPS binding address (%s) is set but neither auto TLS (%s) nor manual TLS (%s and %s) are enabled\",\n\t\t\tHttpsBindingAddressVarenv, TLSAutoDomainVarenv, TLSCertFilepathVarenv, TLSCertKeyFilepathVarenv)\n\t}\n\n\tif cnf.VaultPrefix == \"\" {\n\t\tcnf.VaultPrefix = \"cubbyhole/\"\n\t}\n\n\tlog.Println(\"[INFO] HTTP Binding Address:\", cnf.HttpBindingAddress)\n\tlog.Println(\"[INFO] HTTPS Binding Address:\", cnf.HttpsBindingAddress)\n\tlog.Println(\"[INFO] HTTPS Redirect enabled:\", cnf.HttpsRedirectEnabled)\n\tlog.Println(\"[INFO] TLS Auto Domain:\", cnf.TLSAutoDomain)\n\tlog.Println(\"[INFO] TLS Cert Filepath:\", cnf.TLSCertFilepath)\n\tlog.Println(\"[INFO] TLS Cert Key Filepath:\", cnf.TLSCertKeyFilepath)\n\tlog.Println(\"[INFO] Vault prefix:\", cnf.VaultPrefix)\n\tlog.Println(\"[INFO] Allowed Origins:\", cnf.AllowedOrigins)\n\n\treturn cnf\n}\n"
  },
  {
    "path": "internal/config_test.go",
    "content": "package internal\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLoadConfig(t *testing.T) {\n\t_ = os.Setenv(HttpBindingAddressVarenv, \":8080\")\n\t_ = os.Setenv(VaultPrefixenv, \"cubbyhole/\")\n\t_ = os.Setenv(AllowedOriginsVarenv, \"http://localhost,https://example.com\")\n\tdefer func() {\n\t\t_ = os.Unsetenv(HttpBindingAddressVarenv)\n\t\t_ = os.Unsetenv(VaultPrefixenv)\n\t\t_ = os.Unsetenv(AllowedOriginsVarenv)\n\t}()\n\n\tcnf := LoadConfig()\n\n\tassert.Equal(t, \":8080\", cnf.HttpBindingAddress)\n\tassert.Equal(t, \"cubbyhole/\", cnf.VaultPrefix)\n\tassert.False(t, cnf.HttpsRedirectEnabled)\n\tassert.Equal(t, []string{\"http://localhost\", \"https://example.com\"}, cnf.AllowedOrigins)\n}\n"
  },
  {
    "path": "internal/handlers.go",
    "content": "package internal\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"mime\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/labstack/echo/v4\"\n)\n\n// tokenRegex matches valid Vault token formats for hv.sb and legacy tokens.\nvar tokenRegex = regexp.MustCompile(`^hv[sb]\\.(?:[A-Za-z0-9]{24}|[A-Za-z0-9_-]{91,})$`)\n\n// TokenResponse represents the API response when creating a new secret message.\n// It includes a token for retrieving the message, and optional file token and name\n// if a file was uploaded alongside the message.\ntype TokenResponse struct {\n\t// Token is the unique identifier for retrieving the secret message.\n\tToken string `json:\"token\"`\n\t// FileToken is the unique identifier for retrieving an uploaded file (optional).\n\tFileToken string `json:\"filetoken,omitempty\"`\n\t// FileName is the original name of the uploaded file (optional).\n\tFileName string `json:\"filename,omitempty\"`\n}\n\n// MsgResponse represents the API response when retrieving a secret message.\ntype MsgResponse struct {\n\t// Msg is the secret message content retrieved from Vault.\n\tMsg string `json:\"msg\"`\n}\n\n// SecretHandlers provides HTTP handler methods for creating and retrieving secret messages.\ntype SecretHandlers struct {\n\t// store is the backend storage implementation (Vault) for secret messages.\n\tstore SecretMsgStorer\n}\n\n// NewSecretHandlers creates a new SecretHandlers instance with the provided storage backend.\nfunc NewSecretHandlers(s SecretMsgStorer) *SecretHandlers {\n\treturn &SecretHandlers{s}\n}\n\n// validateMsg checks if the provided message is non-empty and within size limits.\nfunc validateMsg(msg string) error {\n\tif msg == \"\" {\n\t\treturn fmt.Errorf(\"message is required\")\n\t}\n\n\t// 1MB limit for text\n\tif len(msg) > 1*1024*1024 {\n\t\treturn fmt.Errorf(\"message too large\")\n\t}\n\n\treturn nil\n}\n\n// isValidTTL checks if the provided TTL string is a valid duration between 1 minute and 7 days.\nfunc isValidTTL(ttl string) bool {\n\t// Verify duration\n\td, err := time.ParseDuration(ttl)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\t// validate duration length (between 1 minute and 7 days)\n\tif d < 1*time.Minute || d > 168*time.Hour {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// validateFileUpload checks the uploaded file for size and filename validity.\nfunc validateFileUpload(file *multipart.FileHeader) error {\n\t// Parse Content-Disposition to extract filename\n\tmediatype, params, err := mime.ParseMediaType(file.Header.Get(\"Content-Disposition\"))\n\tif mediatype != \"form-data\" || err != nil {\n\t\treturn fmt.Errorf(\"invalid file upload\")\n\t}\n\n\t// Check file size\n\tif file.Size > 50*1024*1024 {\n\t\treturn fmt.Errorf(\"file too large\")\n\t}\n\n\t// Check filename for path traversal\n\tif strings.Contains(params[\"filename\"], \"..\") ||\n\t\tstrings.Contains(params[\"filename\"], \"/\") ||\n\t\tstrings.Contains(params[\"filename\"], \"\\\\\") ||\n\t\tstrings.Contains(file.Filename, \"..\") ||\n\t\tstrings.Contains(file.Filename, \"/\") ||\n\t\tstrings.Contains(file.Filename, \"\\\\\") {\n\t\treturn fmt.Errorf(\"invalid filename\")\n\t}\n\n\treturn nil\n}\n\n// validateVaultToken checks the format of Vault-generated tokens\nfunc validateVaultToken(token string) error {\n\t// Check token format\n\tif !tokenRegex.MatchString(token) {\n\t\treturn fmt.Errorf(\"invalid token format: %s\", token)\n\t}\n\treturn nil\n}\n\n// CreateMsgHandler handles POST requests to create a new self-destructing secret message.\n// It accepts form data with 'msg' (required), 'ttl' (optional time-to-live), and 'file' (optional file upload).\n// Files are base64 encoded before storage. Maximum file size is 50MB (enforced by middleware).\n// Returns a JSON response with token(s) for retrieving the message and/or file.\nfunc (s SecretHandlers) CreateMsgHandler(ctx echo.Context) error {\n\n\tmsg := ctx.FormValue(\"msg\")\n\tif err := validateMsg(msg); err != nil {\n\t\treturn echo.NewHTTPError(http.StatusBadRequest, err.Error())\n\t}\n\n\t// Get TTL (if any)\n\tttl := ctx.FormValue(\"ttl\")\n\tif ttl != \"\" && !isValidTTL(ttl) {\n\t\treturn echo.NewHTTPError(http.StatusBadRequest, \"invalid TTL format\")\n\t}\n\n\tvar tr TokenResponse\n\t// Upload file if any\n\tfile, err := ctx.FormFile(\"file\")\n\tif err == nil {\n\t\tif err := validateFileUpload(file); err != nil {\n\t\t\treturn echo.NewHTTPError(http.StatusBadRequest, err.Error())\n\t\t}\n\n\t\tsrc, err := file.Open()\n\t\tif err != nil {\n\t\t\treturn echo.NewHTTPError(http.StatusInternalServerError, err)\n\t\t}\n\t\tdefer func() { _ = src.Close() }()\n\n\t\tb, err := io.ReadAll(src)\n\t\tif err != nil {\n\t\t\treturn echo.NewHTTPError(http.StatusInternalServerError, err)\n\t\t}\n\n\t\tif len(b) > 0 {\n\t\t\ttr.FileName = file.Filename\n\t\t\tencodedFile := base64.StdEncoding.EncodeToString(b)\n\n\t\t\tfiletoken, err := s.store.Store(encodedFile, ttl)\n\t\t\tif err != nil {\n\t\t\t\treturn echo.NewHTTPError(http.StatusInternalServerError, err)\n\t\t\t}\n\t\t\ttr.FileToken = filetoken\n\t\t}\n\t}\n\n\t// Handle the secret message\n\ttr.Token, err = s.store.Store(msg, ttl)\n\tif err != nil {\n\t\tctx.Logger().Errorf(\"Failed to store secret: %v\", err)\n\t\treturn echo.NewHTTPError(http.StatusInternalServerError, \"failed to store secret\")\n\t}\n\n\treturn ctx.JSON(http.StatusOK, tr)\n}\n\n// GetMsgHandler handles GET requests to retrieve a self-destructing secret message.\n// Accepts a 'token' query parameter. The message is deleted from Vault after retrieval,\n// making it accessible only once. Returns a JSON response with the message content.\nfunc (s SecretHandlers) GetMsgHandler(ctx echo.Context) error {\n\ttoken := ctx.QueryParam(\"token\")\n\tif err := validateVaultToken(token); err != nil {\n\t\treturn echo.NewHTTPError(http.StatusBadRequest, err.Error())\n\t}\n\n\tm, err := s.store.Get(token)\n\tif err != nil {\n\t\tctx.Logger().Errorf(\"Failed to retrieve secret: %v\", err)\n\t\treturn echo.NewHTTPError(http.StatusNotFound, \"secret not found or already consumed\")\n\t}\n\tr := &MsgResponse{\n\t\tMsg: m,\n\t}\n\treturn ctx.JSON(http.StatusOK, r)\n}\n\n// healthHandler provides a simple health check endpoint.\n// Returns HTTP 200 OK when the application is running.\nfunc healthHandler(ctx echo.Context) error {\n\treturn ctx.String(http.StatusOK, http.StatusText(http.StatusOK))\n}\n\n// redirectHandler redirects the root path to the message creation page.\nfunc redirectHandler(ctx echo.Context) error {\n\treturn ctx.Redirect(http.StatusPermanentRedirect, \"/msg\")\n}\n"
  },
  {
    "path": "internal/handlers_test.go",
    "content": "package internal\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype FakeSecretMsgStorer struct {\n\tmsg           string\n\ttoken         string\n\terr           error\n\tlastUsedToken string\n\tlastMsg       string\n}\n\nfunc (f *FakeSecretMsgStorer) Get(token string) (msg string, err error) {\n\tf.lastUsedToken = token\n\treturn f.msg, f.err\n}\n\nfunc (f *FakeSecretMsgStorer) Store(msg string, ttl string) (token string, err error) {\n\tf.lastMsg = msg\n\treturn f.token, f.err\n}\n\nfunc TestGetMsgHandler(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\ttoken          string\n\t\tstoredMsg      string\n\t\tstoreErr       error\n\t\texpectedStatus int\n\t\texpectedMsg    string\n\t\texpectError    bool\n\t}{\n\t\t{\n\t\t\tname:           \"successful message retrieval\",\n\t\t\ttoken:          \"hvs.CABAAAAAAQAAAAAAAAAABBBB\",\n\t\t\tstoredMsg:      \"secret\",\n\t\t\tstoreErr:       nil,\n\t\t\texpectedStatus: http.StatusOK,\n\t\t\texpectedMsg:    \"{\\\"msg\\\":\\\"secret\\\"}\\n\",\n\t\t\texpectError:    false,\n\t\t},\n\t\t{\n\t\t\tname:           \"message retrieval with error\",\n\t\t\ttoken:          \"hvs.CABAAAAAAQAAAAAAAAAABBBB\",\n\t\t\tstoredMsg:      \"secret\",\n\t\t\tstoreErr:       errors.New(\"expired\"),\n\t\t\texpectedStatus: http.StatusNotFound,\n\t\t\texpectedMsg:    \"\",\n\t\t\texpectError:    true,\n\t\t},\n\t\t{\n\t\t\tname:           \"invalid token format\",\n\t\t\ttoken:          \"invalid-token-123\",\n\t\t\tstoredMsg:      \"\",\n\t\t\tstoreErr:       nil,\n\t\t\texpectedStatus: http.StatusBadRequest,\n\t\t\texpectedMsg:    \"\",\n\t\t\texpectError:    true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\te := echo.New()\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/?token=\"+tt.token, nil)\n\t\t\trec := httptest.NewRecorder()\n\t\t\tc := e.NewContext(req, rec)\n\n\t\t\ts := &FakeSecretMsgStorer{msg: tt.storedMsg, err: tt.storeErr}\n\t\t\th := NewSecretHandlers(s)\n\t\t\terr := h.GetMsgHandler(c)\n\n\t\t\tif tt.expectError {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tif assert.IsType(t, &echo.HTTPError{}, err) {\n\t\t\t\t\tv, _ := err.(*echo.HTTPError)\n\t\t\t\t\tassert.Equal(t, tt.expectedStatus, v.Code)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, tt.token, s.lastUsedToken)\n\t\t\t\tassert.Equal(t, tt.expectedStatus, rec.Code)\n\t\t\t\tassert.Equal(t, tt.expectedMsg, rec.Body.String())\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestHealthHandler(t *testing.T) {\n\te := echo.New()\n\treq := httptest.NewRequest(http.MethodGet, \"/\", nil)\n\trec := httptest.NewRecorder()\n\tc := e.NewContext(req, rec)\n\n\terr := healthHandler(c)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, http.StatusOK, rec.Code)\n}\n\nfunc TestRedirectHandler(t *testing.T) {\n\te := echo.New()\n\treq := httptest.NewRequest(http.MethodGet, \"/\", nil)\n\trec := httptest.NewRecorder()\n\tc := e.NewContext(req, rec)\n\n\terr := redirectHandler(c)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, http.StatusPermanentRedirect, rec.Code)\n\tassert.Equal(t, \"/msg\", rec.Result().Header.Get(\"Location\"))\n}\n\nfunc TestIsValidTTL(t *testing.T) {\n\ttests := []struct {\n\t\tttl   string\n\t\tvalid bool\n\t}{\n\t\t{\"1h\", true},\n\t\t{\"30m\", true},\n\t\t{\"2h30m\", true},\n\t\t{\"48h\", true},\n\t\t{\"168h\", true},     // 7 days - maximum\n\t\t{\"169h\", false},    // exceeds maximum\n\t\t{\"30s\", false},     // below minimum\n\t\t{\"0h\", false},      // zero duration\n\t\t{\"\", false},        // empty\n\t\t{\"invalid\", false}, // invalid format\n\t\t{\"1d\", false},      // 'd' not supported by Go\n\t\t{\"-1h\", false},     // negative duration\n\t}\n\n\tfor _, tt := range tests {\n\t\tresult := isValidTTL(tt.ttl)\n\t\tassert.Equal(t, result, tt.valid)\n\t}\n}\nfunc TestValidateMsg(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\tmsg     string\n\t\twantErr bool\n\t}{\n\t\t{\"valid message\", \"test secret\", false},\n\t\t{\"empty message\", \"\", true},\n\t\t{\"message too large\", strings.Repeat(\"a\", 1024*1024+1), true},\n\t\t{\"message at limit\", strings.Repeat(\"a\", 1024*1024), false},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\terr := validateMsg(tt.msg)\n\t\t\tif tt.wantErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCreateMsgHandler(t *testing.T) {\n\ttests := []struct {\n\t\tname       string\n\t\tmsg        string\n\t\tttl        string\n\t\terrMessage string\n\t}{\n\t\t{\"valid message and ttl\", \"hello world\", \"1h\", \"\"},\n\t\t{\"valid message, no ttl\", \"hello world\", \"\", \"\"},\n\t\t{\"empty message\", \"\", \"1h\", \"message is required\"},\n\t\t{\"message too large\", strings.Repeat(\"a\", 1024*1024+1), \"1h\", \"message too large\"},\n\t\t{\"invalid ttl\", \"hello world\", \"30s\", \"invalid TTL format\"},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\te := echo.New()\n\t\t\tform := make(url.Values)\n\t\t\tform.Set(\"msg\", tt.msg)\n\t\t\tform.Set(\"ttl\", tt.ttl)\n\n\t\t\treq := httptest.NewRequest(http.MethodPost, \"/secret\", strings.NewReader(form.Encode()))\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm)\n\t\t\trec := httptest.NewRecorder()\n\t\t\tc := e.NewContext(req, rec)\n\n\t\t\ts := &FakeSecretMsgStorer{token: \"testtoken\"}\n\t\t\th := NewSecretHandlers(s)\n\t\t\terr := h.CreateMsgHandler(c)\n\n\t\t\tif tt.errMessage != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tif httpErr, ok := err.(*echo.HTTPError); ok {\n\t\t\t\t\tassert.Equal(t, http.StatusBadRequest, httpErr.Code)\n\t\t\t\t\tassert.Equal(t, tt.errMessage, httpErr.Message)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, http.StatusOK, rec.Code)\n\t\t\t\tassert.Equal(t, tt.msg, s.lastMsg)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCreateMsgHandlerWithFile(t *testing.T) {\n\ttests := []struct {\n\t\tname         string\n\t\tmsg          string\n\t\tttl          string\n\t\tfileName     string\n\t\tfileContent  []byte\n\t\texpectError  bool\n\t\texpectedCode int\n\t\tcheckToken   bool\n\t\tcheckFile    bool\n\t}{\n\t\t{\n\t\t\tname:         \"valid message with file\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"1h\",\n\t\t\tfileName:     \"test.txt\",\n\t\t\tfileContent:  []byte(\"file content\"),\n\t\t\texpectError:  false,\n\t\t\texpectedCode: http.StatusOK,\n\t\t\tcheckToken:   true,\n\t\t\tcheckFile:    true,\n\t\t},\n\t\t{\n\t\t\tname:         \"valid message with file, no TTL\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"\",\n\t\t\tfileName:     \"document.pdf\",\n\t\t\tfileContent:  []byte(\"PDF content here\"),\n\t\t\texpectError:  false,\n\t\t\texpectedCode: http.StatusOK,\n\t\t\tcheckToken:   true,\n\t\t\tcheckFile:    true,\n\t\t},\n\t\t{\n\t\t\tname:         \"empty file should not create file token\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"1h\",\n\t\t\tfileName:     \"empty.txt\",\n\t\t\tfileContent:  []byte{},\n\t\t\texpectError:  false,\n\t\t\texpectedCode: http.StatusOK,\n\t\t\tcheckToken:   true,\n\t\t\tcheckFile:    false,\n\t\t},\n\t\t{\n\t\t\tname:         \"file with path traversal\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"1h\",\n\t\t\tfileName:     \"../etc/passwd\",\n\t\t\tfileContent:  []byte(\"malicious\"),\n\t\t\texpectError:  true,\n\t\t\texpectedCode: http.StatusBadRequest,\n\t\t},\n\t\t{\n\t\t\tname:         \"file with slash in name\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"1h\",\n\t\t\tfileName:     \"path/to/file.txt\",\n\t\t\tfileContent:  []byte(\"content\"),\n\t\t\texpectError:  true,\n\t\t\texpectedCode: http.StatusBadRequest,\n\t\t},\n\t\t{\n\t\t\tname:         \"file too big\",\n\t\t\tmsg:          \"secret message\",\n\t\t\tttl:          \"1h\",\n\t\t\tfileName:     \"bigfile.txt\",\n\t\t\tfileContent:  make([]byte, 50*1024*1024+1), // 50MB + 1 byte\n\t\t\texpectError:  true,\n\t\t\texpectedCode: http.StatusBadRequest,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create multipart form\n\t\t\tbody := &bytes.Buffer{}\n\t\t\twriter := multipart.NewWriter(body)\n\n\t\t\t// Add message field\n\t\t\terr := writer.WriteField(\"msg\", tt.msg)\n\t\t\tassert.NoError(t, err)\n\n\t\t\t// Add TTL field if provided\n\t\t\tif tt.ttl != \"\" {\n\t\t\t\terr = writer.WriteField(\"ttl\", tt.ttl)\n\t\t\t\tassert.NoError(t, err)\n\t\t\t}\n\n\t\t\t// Add file field\n\t\t\tpart, err := writer.CreateFormFile(\"file\", tt.fileName)\n\t\t\tassert.NoError(t, err)\n\t\t\t_, err = part.Write(tt.fileContent)\n\t\t\tassert.NoError(t, err)\n\n\t\t\terr = writer.Close()\n\t\t\tassert.NoError(t, err)\n\n\t\t\t// Create request\n\t\t\te := echo.New()\n\t\t\treq := httptest.NewRequest(http.MethodPost, \"/secret\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, writer.FormDataContentType())\n\t\t\trec := httptest.NewRecorder()\n\t\t\tc := e.NewContext(req, rec)\n\n\t\t\t// Create fake store that returns tokens\n\t\t\ts := &FakeSecretMsgStorer{token: \"msg-token-123\"}\n\t\t\th := NewSecretHandlers(s)\n\n\t\t\t// Execute handler\n\t\t\thandlerErr := h.CreateMsgHandler(c)\n\n\t\t\tif tt.expectError {\n\t\t\t\tassert.Error(t, handlerErr)\n\t\t\t\tif httpErr, ok := handlerErr.(*echo.HTTPError); ok {\n\t\t\t\t\tassert.Equal(t, tt.expectedCode, httpErr.Code)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, handlerErr)\n\t\t\t\tassert.Equal(t, tt.expectedCode, rec.Code)\n\n\t\t\t\t// Parse response\n\t\t\t\tvar response TokenResponse\n\t\t\t\terr := json.Unmarshal(rec.Body.Bytes(), &response)\n\t\t\t\tassert.NoError(t, err)\n\n\t\t\t\tif tt.checkToken {\n\t\t\t\t\tassert.Equal(t, \"msg-token-123\", response.Token)\n\t\t\t\t\tassert.Equal(t, tt.msg, s.lastMsg)\n\t\t\t\t}\n\n\t\t\t\tif tt.checkFile {\n\t\t\t\t\tassert.NotEmpty(t, response.FileToken)\n\t\t\t\t\tassert.Equal(t, tt.fileName, response.FileName)\n\t\t\t\t} else {\n\t\t\t\t\tassert.Empty(t, response.FileToken)\n\t\t\t\t\tassert.Empty(t, response.FileName)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/server.go",
    "content": "// Package internal provides HTTP server setup and request handlers for the sup3rS3cretMes5age application.\n// It includes server lifecycle management with graceful shutdown, middleware configuration,\n// route setup, and integration with HashiCorp Vault for secure message storage.\npackage internal\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/labstack/echo/v4/middleware\"\n\t\"golang.org/x/crypto/acme\"\n\t\"golang.org/x/crypto/acme/autocert\"\n)\n\n// Server encapsulates the HTTP/HTTPS server configuration and lifecycle management.\n// It provides testable server initialization and graceful shutdown capabilities.\ntype Server struct {\n\techo        *echo.Echo\n\tconfig      conf\n\thandlers    *SecretHandlers\n\thttpServer  *http.Server\n\thttpsServer *http.Server\n}\n\n// NewServer creates a new Server instance with the provided configuration and handlers.\n// It configures Echo with all middleware and routes but does not start the server.\n// This allows the server to be tested without binding to network ports.\nfunc NewServer(cnf conf, handlers *SecretHandlers) *Server {\n\te := echo.New()\n\te.HideBanner = true\n\n\t// Configure Auto TLS if enabled\n\tif cnf.TLSAutoDomain != \"\" {\n\t\te.AutoTLSManager.HostPolicy = autocert.HostWhitelist(cnf.TLSAutoDomain)\n\t\te.AutoTLSManager.Cache = autocert.DirCache(\"/var/www/.cache\")\n\t}\n\n\ts := &Server{\n\t\techo:     e,\n\t\tconfig:   cnf,\n\t\thandlers: handlers,\n\t}\n\n\tsetupMiddlewares(e, cnf)\n\tsetupRoutes(e, handlers)\n\n\treturn s\n}\n\n// Start begins listening for HTTP and/or HTTPS requests based on configuration.\n// It supports three modes:\n// 1. HTTP only (when only HttpBindingAddress is set)\n// 2. HTTPS only with Auto TLS or Manual TLS\n// 3. Both HTTP and HTTPS (HTTP typically for redirect)\n//\n// The function blocks until the server is shut down via context cancellation\n// or encounters a fatal error.\nfunc (s *Server) Start(ctx context.Context) error {\n\t// Channel to collect errors from goroutines\n\terrChan := make(chan error, 2)\n\n\t// Start HTTP server if configured\n\tif s.config.HttpBindingAddress != \"\" {\n\t\tif s.config.HttpsBindingAddress != \"\" {\n\t\t\t// Both HTTP and HTTPS - run HTTP in goroutine\n\t\t\tgo func() {\n\t\t\t\tif err := s.startHTTP(); err != nil && err != http.ErrServerClosed {\n\t\t\t\t\terrChan <- err\n\t\t\t\t}\n\t\t\t}()\n\t\t} else {\n\t\t\t// HTTP only\n\t\t\tgo func() {\n\t\t\t\tif err := s.startHTTP(); err != nil && err != http.ErrServerClosed {\n\t\t\t\t\terrChan <- err\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t}\n\n\t// Start HTTPS server if TLS is configured\n\tif s.config.HttpsBindingAddress != \"\" || s.config.TLSAutoDomain != \"\" || s.config.TLSCertFilepath != \"\" {\n\t\tgo func() {\n\t\t\tif err := s.startHTTPS(); err != nil && err != http.ErrServerClosed {\n\t\t\t\terrChan <- err\n\t\t\t}\n\t\t}()\n\t}\n\n\t// Wait for context cancellation or error\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn s.Shutdown(context.Background())\n\tcase err := <-errChan:\n\t\treturn err\n\t}\n}\n\n// startHTTP starts the HTTP server on the configured binding address.\nfunc (s *Server) startHTTP() error {\n\ts.httpServer = &http.Server{\n\t\tAddr:           s.config.HttpBindingAddress,\n\t\tHandler:        s.echo,\n\t\tReadTimeout:    10 * time.Second,\n\t\tWriteTimeout:   10 * time.Second,\n\t\tIdleTimeout:    120 * time.Second,\n\t\tMaxHeaderBytes: 1 << 20, // 1MB\n\t}\n\n\ts.echo.Logger.Infof(\"Starting HTTP server on %s\", s.config.HttpBindingAddress)\n\treturn s.httpServer.ListenAndServe()\n}\n\n// startHTTPS starts the HTTPS server with TLS configuration.\n// Supports both automatic TLS (Let's Encrypt) and manual certificate configuration.\nfunc (s *Server) startHTTPS() error {\n\tautoTLSManager := autocert.Manager{\n\t\tPrompt: autocert.AcceptTOS,\n\t\tCache:  autocert.DirCache(\"/var/www/.cache\"),\n\t}\n\n\t// Use HTTPS binding address if set, otherwise default to :443\n\taddr := s.config.HttpsBindingAddress\n\tif addr == \"\" {\n\t\taddr = \":443\"\n\t}\n\n\ts.httpsServer = &http.Server{\n\t\tAddr:           addr,\n\t\tHandler:        s.echo,\n\t\tReadTimeout:    10 * time.Second,\n\t\tWriteTimeout:   10 * time.Second,\n\t\tIdleTimeout:    120 * time.Second,\n\t\tMaxHeaderBytes: 1 << 20, // 1MB\n\t\tTLSConfig: &tls.Config{\n\t\t\tGetCertificate:           autoTLSManager.GetCertificate,\n\t\t\tNextProtos:               []string{acme.ALPNProto},\n\t\t\tMinVersion:               tls.VersionTLS12,\n\t\t\tCurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.X25519, tls.CurveP256},\n\t\t\tPreferServerCipherSuites: true,\n\t\t\tCipherSuites: []uint16{\n\t\t\t\t// TLS 1.2 safe cipher suites\n\t\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n\t\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\t\t\ttls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\n\t\t\t\ttls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n\t\t\t\ttls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,\n\t\t\t\ttls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n\t\t\t\t// TLS 1.3 cipher suites\n\t\t\t\ttls.TLS_AES_128_GCM_SHA256,\n\t\t\t\ttls.TLS_AES_256_GCM_SHA384,\n\t\t\t\ttls.TLS_CHACHA20_POLY1305_SHA256,\n\t\t\t},\n\t\t},\n\t}\n\n\ts.echo.Logger.Infof(\"Starting HTTPS server on %s\", addr)\n\n\t// Start with manual certificates if provided, otherwise use auto TLS\n\tif s.config.TLSCertFilepath != \"\" && s.config.TLSCertKeyFilepath != \"\" {\n\t\treturn s.httpsServer.ListenAndServeTLS(s.config.TLSCertFilepath, s.config.TLSCertKeyFilepath)\n\t}\n\n\treturn s.httpsServer.ListenAndServeTLS(\"\", \"\")\n}\n\n// Shutdown gracefully shuts down the server without interrupting active connections.\n// It stops accepting new requests and waits for existing requests to complete\n// within the provided context timeout.\nfunc (s *Server) Shutdown(ctx context.Context) error {\n\ts.echo.Logger.Info(\"Shutting down server...\")\n\n\tif s.httpServer != nil {\n\t\tif err := s.httpServer.Shutdown(ctx); err != nil {\n\t\t\ts.echo.Logger.Errorf(\"HTTP server shutdown error: %v\", err)\n\t\t}\n\t}\n\n\tif s.httpsServer != nil {\n\t\tif err := s.httpsServer.Shutdown(ctx); err != nil {\n\t\t\ts.echo.Logger.Errorf(\"HTTPS server shutdown error: %v\", err)\n\t\t}\n\t}\n\n\treturn s.echo.Shutdown(ctx)\n}\n\n// handler returns the underlying http.Handler for testing purposes.\n// This allows tests to use httptest.ResponseRecorder without starting a real server.\nfunc (s *Server) handler() http.Handler {\n\treturn s.echo\n}\n\n// setupMiddlewares configures Echo's middleware stack with security, rate limiting, and logging.\n// It applies HTTPS redirect (if enabled), CORS policy, rate limiting (5 RPS), request logging,\n// security headers (CSP, XSS protection, HSTS), body size limits (50MB), and panic recovery.\n// Middleware is applied in order: pre-routing (HTTPS redirect), then request-level middleware.\nfunc setupMiddlewares(e *echo.Echo, cnf conf) {\n\tif cnf.HttpsRedirectEnabled {\n\t\te.Pre(middleware.HTTPSRedirect())\n\t}\n\n\te.Use(middleware.CORSWithConfig(middleware.CORSConfig{\n\t\tAllowOrigins: cnf.AllowedOrigins,\n\t\tAllowMethods: []string{http.MethodGet, http.MethodPost},\n\t\tAllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType},\n\t\tMaxAge:       86400,\n\t}))\n\n\t// Limit to 5 RPS (burst 10) (only human should use this service)\n\te.Use(middleware.RateLimiterWithConfig(middleware.RateLimiterConfig{\n\t\tStore: middleware.NewRateLimiterMemoryStoreWithConfig(\n\t\t\tmiddleware.RateLimiterMemoryStoreConfig{\n\t\t\t\tRate:      5,\n\t\t\t\tBurst:     10,\n\t\t\t\tExpiresIn: 1 * time.Minute,\n\t\t\t},\n\t\t),\n\t\tIdentifierExtractor: func(ctx echo.Context) (string, error) {\n\t\t\treturn ctx.RealIP(), nil\n\t\t},\n\t\tDenyHandler: func(ctx echo.Context, identifier string, err error) error {\n\t\t\treturn ctx.JSON(http.StatusTooManyRequests, map[string]string{\n\t\t\t\t\"error\": \"rate limit exceeded\",\n\t\t\t})\n\t\t},\n\t}))\n\n\t// do not log the /health endpoint\n\te.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{\n\t\tSkipper: func(c echo.Context) bool {\n\t\t\treturn c.Path() == \"/health\"\n\t\t},\n\t}))\n\n\te.Use(middleware.SecureWithConfig(middleware.SecureConfig{\n\t\tXSSProtection:         \"1; mode=block\",\n\t\tContentTypeNosniff:    \"nosniff\",\n\t\tXFrameOptions:         \"DENY\",\n\t\tHSTSMaxAge:            31536000,\n\t\tHSTSPreloadEnabled:    true,\n\t\tContentSecurityPolicy: \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'\",\n\t}))\n\n\te.Use(middleware.BodyLimit(\"50M\"))\n\n\te.Use(middleware.Recover())\n}\n\n// setupRoutes registers all HTTP endpoints and static file routes.\n// API endpoints: GET/POST /secret (secret management), ANY /health (health check), GET / (redirect).\n// Static routes: /msg and /getmsg (HTML pages), /static (assets), /robots.txt (SEO).\nfunc setupRoutes(e *echo.Echo, handlers *SecretHandlers) {\n\te.GET(\"/\", redirectHandler)\n\n\te.File(\"/robots.txt\", \"static/robots.txt\")\n\n\te.Any(\"/health\", healthHandler)\n\n\te.GET(\"/secret\", handlers.GetMsgHandler)\n\te.POST(\"/secret\", handlers.CreateMsgHandler)\n\n\te.File(\"/msg\", \"static/index.html\")\n\n\te.File(\"/getmsg\", \"static/getmsg.html\")\n\n\te.Static(\"/static\", \"static\")\n}\n"
  },
  {
    "path": "internal/server_test.go",
    "content": "package internal\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"golang.org/x/crypto/acme/autocert\"\n)\n\nfunc TestNewServer(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\n\tserver := NewServer(cnf, handlers)\n\n\tassert.NotNil(t, server)\n\tassert.NotNil(t, server.echo)\n\tassert.NotNil(t, server.handlers)\n\tassert.Equal(t, cnf.HttpBindingAddress, server.config.HttpBindingAddress)\n}\n\nfunc TestServerHandler(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\t// Test health endpoint\n\treq := httptest.NewRequest(http.MethodGet, \"/health\", nil)\n\trec := httptest.NewRecorder()\n\tserver.handler().ServeHTTP(rec, req)\n\n\tassert.Equal(t, http.StatusOK, rec.Code)\n\tassert.Equal(t, \"OK\", rec.Body.String())\n}\n\nfunc TestServerRoutesRegistered(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\troutes := server.echo.Routes()\n\tassert.NotEmpty(t, routes)\n\n\t// Verify key routes exist\n\trouteMap := make(map[string]bool)\n\tfor _, route := range routes {\n\t\tkey := route.Method + \" \" + route.Path\n\t\trouteMap[key] = true\n\t}\n\n\tassert.True(t, routeMap[\"POST /secret\"], \"POST /secret should be registered\")\n\tassert.True(t, routeMap[\"GET /secret\"], \"GET /secret should be registered\")\n\tassert.True(t, routeMap[\"GET /health\"] || routeMap[\"POST /health\"], \"/health should be registered\")\n\tassert.True(t, routeMap[\"GET /\"], \"GET / should be registered\")\n}\n\nfunc TestServerWithMiddlewares(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"http://localhost:3000\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\t// Test CORS middleware\n\treq := httptest.NewRequest(http.MethodOptions, \"/secret\", nil)\n\treq.Header.Set(\"Origin\", \"http://localhost:3000\")\n\treq.Header.Set(\"Access-Control-Request-Method\", \"POST\")\n\trec := httptest.NewRecorder()\n\tserver.handler().ServeHTTP(rec, req)\n\n\tassert.Equal(t, \"http://localhost:3000\", rec.Header().Get(\"Access-Control-Allow-Origin\"))\n}\n\nfunc TestServerSecurityHeaders(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\treq := httptest.NewRequest(http.MethodGet, \"/health\", nil)\n\trec := httptest.NewRecorder()\n\tserver.handler().ServeHTTP(rec, req)\n\n\t// Verify security headers\n\tassert.Equal(t, \"1; mode=block\", rec.Header().Get(\"X-XSS-Protection\"))\n\tassert.Equal(t, \"nosniff\", rec.Header().Get(\"X-Content-Type-Options\"))\n\tassert.Equal(t, \"DENY\", rec.Header().Get(\"X-Frame-Options\"))\n\tassert.Contains(t, rec.Header().Get(\"Content-Security-Policy\"), \"default-src 'self'\")\n}\n\nfunc TestServerRedirect(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\treq := httptest.NewRequest(http.MethodGet, \"/\", nil)\n\trec := httptest.NewRecorder()\n\tserver.handler().ServeHTTP(rec, req)\n\n\tassert.Equal(t, http.StatusPermanentRedirect, rec.Code)\n\tassert.Equal(t, \"/msg\", rec.Header().Get(\"Location\"))\n}\n\nfunc TestServerWithTLSAutoDomain(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tTLSAutoDomain:      \"example.com\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\tassert.NotNil(t, server)\n\t// Verify TLS domain is configured (checking the pointer to avoid copylocks)\n\tassert.NotNil(t, server.echo)\n\tassert.Equal(t, \"example.com\", server.config.TLSAutoDomain)\n\tassert.Equal(t, autocert.DirCache(\"/var/www/.cache\"), server.echo.AutoTLSManager.Cache)\n}\n\nfunc TestServerGracefulShutdown(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\n\terr := server.Shutdown(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestServerHandlersIntegration(t *testing.T) {\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\t// Use valid Vault token format (hvs. prefix + 24 alphanumeric chars)\n\tvalidToken := \"hvs.CABAAAAAAQAAAAAAAAAABBBB\"\n\tstorage := &FakeSecretMsgStorer{\n\t\ttoken: validToken,\n\t\tmsg:   \"secret message\",\n\t}\n\thandlers := NewSecretHandlers(storage)\n\tserver := NewServer(cnf, handlers)\n\n\t// Test GET /secret with valid token\n\treq := httptest.NewRequest(http.MethodGet, \"/secret?token=\"+validToken, nil)\n\trec := httptest.NewRecorder()\n\tserver.handler().ServeHTTP(rec, req)\n\n\tassert.Equal(t, http.StatusOK, rec.Code)\n\tassert.Contains(t, rec.Body.String(), \"secret message\")\n}\n\nfunc TestServerRateLimiting(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping rate limit test in short mode\")\n\t}\n\n\tcnf := conf{\n\t\tHttpBindingAddress: \":8080\",\n\t\tVaultPrefix:        \"cubbyhole/\",\n\t\tAllowedOrigins:     []string{\"*\"},\n\t}\n\thandlers := NewSecretHandlers(&FakeSecretMsgStorer{})\n\tserver := NewServer(cnf, handlers)\n\n\t// Make rapid requests to trigger rate limit\n\tsuccessCount := 0\n\trateLimitCount := 0\n\n\tfor i := 0; i < 20; i++ {\n\t\treq := httptest.NewRequest(http.MethodGet, \"/health\", nil)\n\t\treq.Header.Set(\"X-Real-IP\", \"192.168.1.1\")\n\t\trec := httptest.NewRecorder()\n\t\tserver.handler().ServeHTTP(rec, req)\n\n\t\tswitch rec.Code {\n\t\tcase http.StatusOK:\n\t\t\tsuccessCount++\n\t\tcase http.StatusTooManyRequests:\n\t\t\trateLimitCount++\n\t\t}\n\t}\n\n\t// Should have some rate limited requests\n\tassert.Greater(t, rateLimitCount, 0, \"Rate limiter should have triggered\")\n}\n"
  },
  {
    "path": "internal/vault.go",
    "content": "package internal\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/hashicorp/vault/api\"\n)\n\n// SecretMsgStorer defines the interface for storing and retrieving self-destructing messages.\n// Implementations must ensure messages are deleted after first retrieval (one-time access).\ntype SecretMsgStorer interface {\n\t// Store saves a message with the specified TTL and returns a unique retrieval token.\n\tStore(string, ttl string) (token string, err error)\n\t// Get retrieves a message by token and deletes it from storage (one-time read).\n\tGet(token string) (msg string, err error)\n}\n\n// vault implements SecretMsgStorer using HashiCorp Vault's cubbyhole backend.\n// It manages one-time tokens and automatic token renewal for secure message storage.\ntype vault struct {\n\t// address is the Vault server URL (read from VAULT_ADDR if empty).\n\taddress string\n\t// prefix is the Vault storage path prefix (e.g., \"cubbyhole/\").\n\tprefix string\n\t// token is the Vault authentication token (read from VAULT_TOKEN if empty).\n\ttoken string\n}\n\n// NewVault creates a new vault client and starts a background goroutine for token renewal.\n// If address or token are empty, they will be read from VAULT_ADDR and VAULT_TOKEN\n// environment variables respectively. The prefix determines the Vault storage path.\nfunc NewVault(address string, prefix string, token string) *vault {\n\tv := &vault{address, prefix, token}\n\n\tgo v.newVaultClientToRenewToken()\n\treturn v\n}\n\n// Store saves a message to Vault with the specified time-to-live (TTL).\n// Default TTL is 48 hours if not specified. Maximum TTL is 168 hours (7 days).\n// Returns a unique one-time token for retrieving the message.\n// The token can be used exactly twice: once to store and once to retrieve.\nfunc (v vault) Store(msg string, ttl string) (token string, err error) {\n\t// Default TTL\n\tif ttl == \"\" {\n\t\tttl = \"48h\"\n\t}\n\n\tt, err := v.createOneTimeToken(ttl)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif v.writeMsgToVault(t, msg) != nil {\n\t\treturn \"\", err\n\t}\n\treturn t, nil\n}\n\n// createOneTimeToken creates a non-renewable Vault token with exactly 2 uses.\n// The token is used once to write the message and once to read it, ensuring\n// one-time access. The token automatically expires after the specified TTL.\nfunc (v vault) createOneTimeToken(ttl string) (string, error) {\n\tc, err := v.newVaultClient()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tt := c.Auth().Token()\n\n\tvar notRenewable bool\n\ts, err := t.Create(&api.TokenCreateRequest{\n\t\tMetadata:       map[string]string{\"name\": \"placeholder\"},\n\t\tExplicitMaxTTL: ttl,\n\t\tNumUses:        2, //1 to create 2 to get\n\t\tRenewable:      &notRenewable,\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn s.Auth.ClientToken, nil\n}\n\n// newVaultClient creates a new Vault API client with the configured address and token.\n// If the vault address is empty, it defaults to using the VAULT_ADDR environment variable.\n// If the vault token is empty, it defaults to using the VAULT_TOKEN environment variable.\nfunc (v vault) newVaultClient() (*api.Client, error) {\n\tc, err := api.NewClient(api.DefaultConfig())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif v.token != \"\" {\n\t\tc.SetToken(v.token)\n\t}\n\n\tif v.address == \"\" {\n\t\treturn c, nil\n\t}\n\n\terr = c.SetAddress(v.address)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn c, nil\n}\n\n// writeMsgToVault writes a message to Vault using the provided one-time token.\n// The message is stored at the path: /<prefix>/<token>.\n// This consumes the first use of the two-use token.\nfunc (v vault) writeMsgToVault(token, msg string) error {\n\tc, err := v.newVaultClientWithToken(token)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\traw := map[string]interface{}{\"msg\": msg}\n\n\t_, err = c.Logical().Write(\"/\"+v.prefix+token, raw)\n\n\treturn err\n}\n\n// Get retrieves and deletes a message from Vault using the provided token.\n// This consumes the second (final) use of the two-use token, automatically\n// deleting both the message and the token from Vault, ensuring one-time access.\nfunc (v vault) Get(token string) (msg string, err error) {\n\tc, err := v.newVaultClientWithToken(token)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tr, err := c.Logical().Read(v.prefix + token)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn r.Data[\"msg\"].(string), nil\n}\n\n// newVaultClientWithToken creates a Vault client authenticated with a specific token.\n// Used for one-time token operations when storing and retrieving messages.\nfunc (v vault) newVaultClientWithToken(token string) (*api.Client, error) {\n\tc, err := v.newVaultClient()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.SetToken(token)\n\treturn c, nil\n}\n\n// newVaultClientToRenewToken runs in a background goroutine to automatically renew\n// the main Vault authentication token before it expires. This ensures continuous\n// operation of the service without manual token refresh.\nfunc (v vault) newVaultClientToRenewToken() {\n\tc, err := v.newVaultClient()\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\tclient_auth_token := &api.Secret{Auth: &api.SecretAuth{ClientToken: c.Token(), Renewable: true}}\n\n\t/* */\n\tlog.Println(\"renew cycle: begin\")\n\tdefer log.Println(\"renew cycle: end\")\n\n\t// auth token\n\tauthTokenWatcher, err := c.NewLifetimeWatcher(&api.LifetimeWatcherInput{\n\t\tSecret: client_auth_token,\n\t})\n\n\tif err != nil {\n\t\terr := fmt.Errorf(\"unable to initialize auth token lifetime watcher: %w\", err)\n\t\tfmt.Println(err.Error())\n\t}\n\n\tgo authTokenWatcher.Start()\n\tdefer authTokenWatcher.Stop()\n\n\t// monitor events from both watchers\n\tfor {\n\t\tselect {\n\n\t\tcase err := <-authTokenWatcher.DoneCh():\n\t\t\t// Leases created by a token get revoked when the token is revoked.\n\t\t\tfmt.Println(\"Error is :\", err)\n\n\t\t// RenewCh is a channel that receives a message when a successful\n\t\t// renewal takes place and includes metadata about the renewal.\n\t\tcase info := <-authTokenWatcher.RenewCh():\n\t\t\tlog.Printf(\"auth token: successfully renewed; remaining duration: %ds\", info.Secret.Auth.LeaseDuration)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/vault_test.go",
    "content": "package internal\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/vault/api\"\n\tvaulthttp \"github.com/hashicorp/vault/http\"\n\thashivault \"github.com/hashicorp/vault/vault\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc createTestVault(t *testing.T) (net.Listener, *api.Client) {\n\tt.Helper()\n\n\t// Create an in-memory, unsealed core (the \"backend\", if you will).\n\tcore, _, rootToken := hashivault.TestCoreUnsealed(t)\n\n\t// Start an HTTP server for the core.\n\tln, addr := vaulthttp.TestServer(t, core)\n\n\t// Create a client that talks to the server, initially authenticating with\n\t// the root token.\n\tconf := api.DefaultConfig()\n\tconf.Address = addr\n\n\tc, err := api.NewClient(conf)\n\n\tif assert.NoError(t, err) {\n\t\tc.SetToken(rootToken)\n\t\t_, err = c.Sys().Health()\n\t\tassert.NoError(t, err)\n\t}\n\n\treturn ln, c\n}\n\nfunc TestStoreAndGet(t *testing.T) {\n\tln, c := createTestVault(t)\n\tdefer func() { _ = ln.Close() }()\n\n\tv := NewVault(c.Address(), \"secret/test/\", c.Token())\n\tsecret := \"my secret\"\n\ttoken, err := v.Store(secret, \"\")\n\tif assert.NoError(t, err) {\n\t\tmsg, err := v.Get(token)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, secret, msg)\n\t}\n}\n\nfunc TestMsgCanOnlyBeAccessedOnce(t *testing.T) {\n\tln, c := createTestVault(t)\n\tdefer func() { _ = ln.Close() }()\n\n\tv := NewVault(c.Address(), \"secret/test/\", c.Token())\n\tsecret := \"my secret\"\n\ttoken, err := v.Store(secret, \"\")\n\tif assert.NoError(t, err) {\n\t\t_, err = v.Get(token)\n\t\tassert.NoError(t, err)\n\n\t\t_, err = v.Get(token)\n\t\tassert.Error(t, err)\n\t}\n}\n\nfunc TestStoreWithInvalidAddress(t *testing.T) {\n\tv := NewVault(\"http://invalid:9999\", \"secret/\", \"fake-token\")\n\t_, err := v.Store(\"msg\", \"1h\")\n\n\tassert.Error(t, err)\n}\n"
  },
  {
    "path": "web/static/application.css",
    "content": "*{\n  box-sizing: border-box;\n}\n\n.text-center {\n  text-align: center;\n}\n\nhtml,body {\n  min-width: 100vw;\n  min-height: 100vh;\n  font-family: Montserrat, sans-serif;\n  background-image: linear-gradient(to bottom left, #3e366a, #09112f);\n  -webkit-font-smoothing: antialiased;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: transparent;\n  text-shadow: 0 0 5px rgba(0 0 0 50%);\n}\n\nh1{\n  font-weight: 400;\n  margin-bottom: 4px;\n}\n\ntextarea{\n  border-radius: 6px;\n  border: none;\n  padding: 20px;\n  font-size: 20px;\n  min-height: 170px;\n  transition: 200ms ease-in-out;\n  width: 100%;\n}\n\nbutton {\n  cursor: pointer;\n  margin-top: 32px;\n  min-width: 210px;\n  color: rgb(255 255 255);\n  box-shadow: 0 2px 6px 0 rgba(5 15 44 50%);\n  padding: 0 20px;\n  display: inline-block;\n  border-radius: 50px;\n  font-size: 16px;\n  font-weight: 500;\n  height: 40px;\n  line-height: 40px;\n  border: none;\n  box-sizing: border-box;\n  position: relative;\n  transition: 200ms ease-in-out;\n}\n\n.container {\n  position: relative;\n  margin: 0 auto;\n  max-width: 500px;\n  width: 100vw;\n}\n\n.encrypt{\n  background-image: linear-gradient(80deg, #00aeff, #3369e7);\n}\n\n.clipboard{\n  background-image: linear-gradient(284deg, #1cc7d0, #2dde98);\n}\n\n.success-encrypted {\n  position: absolute;\n  top: 0;\n  opacity: 0;\n  visibility: hidden;\n  pointer-events: none;\n  width: 100%;\n}\n\n.subtitle {\n  margin-top: 4px;\n  margin-bottom: 32px;\n  opacity: .9;\n  font-weight: 400;\n}\n\n.send {\n  text-align: center;\n  color: white; \n}\n\ndiv.footer {\n   position: absolute;\n   height: 24px;\n   right: 10px;\n   bottom: 10px;\n}\n\ndiv.footer img {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  width: 32px;\n  height: auto;\n}\n\n.slidecontainer {\n  width: 100%;\n}\n\n.slider {\n  -webkit-appearance: none;\n  width: 100%;\n  height: 25px;\n  border-radius: 5px;\n  background: #d3d3d3;\n  outline: none;\n  opacity: 0.7;\n  -webkit-transition: .2s;\n  transition: opacity .2s;\n}\n\n.slider:hover {\n  opacity: 1;\n}\n\n.slider::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  appearance: none;\n  width: 35px;\n  height: 35px;\n  border-radius: 5px;\n  background: #4CAF50;\n  cursor: pointer;\n}\n\n.slider::-moz-range-thumb {\n  width: 35px;\n  height: 35px;\n  border-radius: 5px;\n  background: #4CAF50;\n  cursor: pointer;\n}\n"
  },
  {
    "path": "web/static/getmsg.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>sup3rS3cretMes5age</title>\n    <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/static/icons/apple-touch-icon.png\">\n    <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/static/icons/favicon-32x32.png\">\n    <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/static/icons/favicon-16x16.png\">\n    <link rel=\"manifest\" href=\"/static/icons/manifest.json\">\n    <link rel=\"mask-icon\" href=\"/static/icons/safari-pinned-tab.svg\" color=\"#5bbad5\">\n    <meta name=\"theme-color\" content=\"#ffffff\">\n    <meta name=\"description\" content=\"Send self-destructing one-time secret messages securely. Messages are automatically deleted after first read.\">\n    <!--Let browser know website is optimized for mobile-->\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <link href=\"/static/montserrat.css\" rel=\"stylesheet\">\n    <link href=\"/static/application.css\" rel=\"stylesheet\">\n    <meta charset=\"UTF-8\">\n    <!-- Facebook/Slack Meta Tags-->\n    <meta property=\"og:title\" content=\"Self Destructing Secure Message\" />\n    <meta property=\"og:image\" content=\"/static/icons/android-chrome-512x512.png\" />\n    <meta property=\"og:site_name\" content=\"sup3rS3cretMes5age\" />\n    <meta property=\"og:description\" content=\"A self destructing one time secure msg service, have fun, stay secure!\" />\n    <meta property=\"og:type\" content=\"website\">\n  </head>\n  <body>\n    <main class=\"send\">\n      <div class=\"container\">\n        <h1>Secret Message</h1>\n        <p class=\"subtitle\">Get your secret one-time read only message</p>\n        <div class=\"slidecontainer\">\n          <h2>Drag the slider to display the Secret Message</h2>\n          <input type=\"range\" min=\"0\" max=\"100\" value=\"0\" step=\"5\" class=\"slider\" id=\"myRange\">\n        </div>\n        <div class=\"input-field\" style=\"display:none\">\n          <textarea id=\"textarea1\" name=\"msg\" class=\"materialize-textarea\" placeholder=\"Message should appear here\" readonly></textarea>\n        </div>\n        <div class=\"button\" style=\"display:none\">\n          <button class=\"btn clipboard\"  type=\"submit\" data-clipboard-target=\"#textarea1\" name=\"action\">Copy to clipboard</button>\n          <button class=\"btn encrypt\"  type=\"submit\" name=\"newMsg\">Send a secret message</button>\n        </div>\n      </div>\n    </main>\n    <footer>\n      <div class=\"footer\">\n        <a href=\"https://github.com/algolia/sup3rS3cretMes5age\" target=\"_blank\" rel=\"noopener noreferrer\">\n            <img src=\"/static/icons/github.png\" alt=\"sup3rS3cretMes5age GitHub repository\">\n        </a>\n      </div>\n    </footer>\n    <script type=\"text/javascript\" src=\"/static/clipboard-2.0.11.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/static/utils.js\"></script>\n    <script type=\"text/javascript\" src=\"/static/getmsg.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "web/static/getmsg.js",
    "content": "/**\n * Secret Message Retrieval Interface\n * \n * Provides slider-based confirmation UI for retrieving one-time secret messages\n * from the /secret API endpoint. Supports both text messages and file downloads\n * with automatic base64 decoding. All event handlers are CSP-compliant.\n */\n\n// Initialize clipboard functionality\ndocument.addEventListener('DOMContentLoaded', function() {\n    new ClipboardJS('.btn');\n});\n\n// slider.oninput\ndocument.getElementById(\"myRange\").addEventListener('input', function() {\n    if (this.value === '100') { // slider.value returns string\n        showSecret();\n    }\n});\n\ndocument.querySelector('.encrypt[name=\"newMsg\"]').addEventListener('click', function() {\n    // Use relative path to avoid open redirect warnings\n    window.location.href = '/';\n});\n\nfunction validateSecretUrl(token) {\n    // Validate token format\n    if (!token || typeof token !== 'string' || !/^[A-Za-z0-9_\\-\\.]+$/.test(token)) {\n        console.error('Invalid token format');\n        showMsg(\"Invalid or missing token\");\n        return null;\n    }\n\n    // Properly encode URL parameters\n    const url = new URL('/secret', window.location.origin);\n    url.searchParams.set('token', token);\n    return url.toString();\n}\n\nfunction showSecret() {\n    const params = (new URL(window.location)).searchParams;\n\n    const urlStr = validateSecretUrl(params.get('token'));\n    if (!urlStr) {\n        return;\n    }\n\n    // Replace jQuery AJAX with fetch\n    fetch(urlStr, {\n        method: 'GET'\n    })\n    .then(response => {\n        if (!response.ok) {\n            throw new Error('Network response was not ok');\n        }\n        return response.json();\n    })\n    .then(data => {\n        showMsg(data.msg, params.get('filetoken'), params.get('filename'));\n    })\n    .catch(error => {\n        console.error(`An error occurred: ${error}`);\n        showMsg(\"Message was already deleted :(\");\n    });\n};\n\nfunction showMsg(msg, filetoken, filename) {\n    // Hide progress bar if it exists\n    const pbar = $('#pbar');\n    if (pbar) {\n        pbar.style.display = 'none';\n    }\n\n    // Set message text\n    const textarea = $('#textarea1');\n    if (textarea) {\n        textarea.value = msg;\n    }\n\n    if (filetoken) {\n        getSecret(filetoken, filename);\n    }\n\n    // Hide slider\n    const slideContainer = $('.slidecontainer');\n    if (slideContainer) {\n        slideContainer.style.display = 'none';\n    }\n\n    // Show secret text box\n    const inputField = $('.input-field');\n    if (inputField) {\n        inputField.style.display = 'block';\n    }\n\n    // Show copy to clipboard button\n    const buttonDiv = $('.button');\n    if (buttonDiv) {\n        buttonDiv.style.display = 'block';\n    }\n\n    // Reset slider (in case of back button)\n    document.getElementById(\"myRange\").value = 0;\n}\n\nfunction getSecret(token, name) {\n    const urlStr = validateSecretUrl(token);\n    if (!urlStr) {\n        return;\n    }\n\n    fetch(urlStr, {\n        method: 'get'\n    }).then(response =>\n        response.json()\n    ).then(json => {\n        saveData(json.msg, name);\n    }).catch(function (err) {\n        console.error(`An error occurred: ${err}`);\n    });\n}\n\nvar saveData = (function () {\n    const a = document.createElement(\"a\");\n    document.body.appendChild(a);\n    a.style.display = \"none\";\n    return function (data, fileName) {\n        const blob = b64toBlob([data], { type: \"octet/stream\" })\n        const url = window.URL.createObjectURL(blob);\n        a.href = url;\n        a.download = fileName;\n        a.click();\n        window.URL.revokeObjectURL(url);\n    };\n}());\n\nfunction b64toBlob(b64Data, contentType, sliceSize) {\n    sliceSize = sliceSize || 512;\n\n    const byteCharacters = atob(b64Data);\n    const byteArrays = [];\n\n    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {\n        const slice = byteCharacters.slice(offset, offset + sliceSize);\n\n        // Use Uint8Array directly without intermediate Array to avoid object injection\n        const byteArray = new Uint8Array(slice.length);\n        for (let i = 0; i < slice.length; i++) {\n            byteArray[i] = slice.charCodeAt(i);\n        }\n\n        byteArrays.push(byteArray);\n    }\n\n    return new Blob(byteArrays, {type: contentType});\n}\n"
  },
  {
    "path": "web/static/icons/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"/mstile-150x150.png\"/>\n            <TileColor>#da532c</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "web/static/icons/manifest.json",
    "content": "{\n    \"name\": \"\",\n    \"icons\": [\n        {\n            \"src\": \"/android-chrome-192x192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/android-chrome-512x512.png\",\n            \"sizes\": \"512x512\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}"
  },
  {
    "path": "web/static/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>sup3rS3cretMes5age</title>\n    <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/static/icons/apple-touch-icon.png\">\n    <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/static/icons/favicon-32x32.png\">\n    <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/static/icons/favicon-16x16.png\">\n    <link rel=\"manifest\" href=\"/static/icons/manifest.json\">\n    <link rel=\"mask-icon\" href=\"/static/icons/safari-pinned-tab.svg\" color=\"#5bbad5\">\n    <meta name=\"theme-color\" content=\"#ffffff\">\n    <meta name=\"description\" content=\"Send self-destructing one-time secret messages securely. Messages are automatically deleted after first read.\">\n    <!--Let browser know website is optimized for mobile-->\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <link href=\"/static/montserrat.css\" rel=\"stylesheet\">\n    <link href=\"/static/application.css\" rel=\"stylesheet\">\n    <meta charset=\"UTF-8\">\n    <!-- Facebook/Slack Meta Tags-->\n    <meta property=\"og:title\" content=\"Self Destructing Secure Message\" />\n    <meta property=\"og:image\" content=\"/static/icons/android-chrome-512x512.png\" />\n    <meta property=\"og:site_name\" content=\"sup3rS3cretMes5age\" />\n    <meta property=\"og:description\" content=\"A self destructing one time secure msg service, have fun, stay secure!\" />\n    <meta property=\"og:type\" content=\"website\">\n  </head>\n  <body>\n    <main class=\"send\">\n      <div class=\"container\">\n        <h1>Secret Message</h1>\n        <p class=\"subtitle\">Send a secret one-time read only message</p>\n        <form id=\"secretform\" action=\"/no-internet\" method=\"POST\" enctype=\"multipart/form-data\">\n          <div class=\"input-field\">\n            Upload Secret File: <input id='file-input' type=\"file\" name=\"file\" size=25><br>\n            <textarea id=\"textarea1\" name=\"msg\" placeholder=\"Paste your message here\" required></textarea>\n          </div>\n          <div class=\"ttl\">\n            Time to expire: \n            <select name=\"ttl\" id=\"ttl\">\n              <option value=\"24h\">24h</option>\n              <option value=\"48h\" selected>48h</option>\n              <option value=\"168h\">week</option>\n            </select>\n          </div>\n          <div class=\"button_wrapper\">\n            <button class=\"encrypt\" type=\"submit\" name=\"action\">Submit\n              <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 268.832 268.832\"><path fill=\"#FFF\" d=\"M265.17 125.577l-80-80c-4.88-4.88-12.796-4.88-17.677 0-4.882 4.882-4.882 12.796 0 17.678l58.66 58.66H12.5c-6.903 0-12.5 5.598-12.5 12.5 0 6.903 5.597 12.5 12.5 12.5h213.654l-58.66 58.662c-4.88 4.882-4.88 12.796 0 17.678 2.44 2.44 5.64 3.66 8.84 3.66s6.398-1.22 8.84-3.66l79.997-80c4.883-4.882 4.883-12.796 0-17.678z\"/></svg>\n            </button>\n          </div>\n        </form>\n        <div class=\"divider\"></div>\n        <div class=\"success-encrypted\">\n          <div class=\"output-field\">\n            <textarea id=\"url\" class=\"textarea\" readonly></textarea>\n          </div>\n          <div class=\"button\">\n            <button class=\"btn clipboard\" data-clipboard-target=\"#url\">Copy to Clipboard</button>\n          </div>\n        </div>\n      </div>\n    </main>\n    <footer>\n      <div class=\"footer\">\n        <a href=\"https://github.com/algolia/sup3rS3cretMes5age\" target=\"_blank\" rel=\"noopener noreferrer\">\n          <img src=\"/static/icons/github.png\" alt=\"sup3rS3cretMes5age GitHub repository\">\n        </a>\n      </div>\n    </footer>\n    <script type=\"text/javascript\" src=\"/static/clipboard-2.0.11.min.js\"></script>\n    <script type=\"text/javascript\" src=\"/static/utils.js\"></script>\n    <script type=\"text/javascript\" src=\"/static/index.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "web/static/index.js",
    "content": "/**\n * Secret Message Creation Interface\n *\n * Processes message creation requests with optional file uploads and custom TTL.\n * Submits data to /secret API endpoint and returns a shareable one-time link.\n * All event handlers are CSP-compliant.\n */\n\n// CSS manipulation helper\nfunction setStyles(element, styles) {\n  Object.assign(element.style, styles);\n}\n\n// Form submission handler\ndocument.addEventListener('DOMContentLoaded', function() {\n  // Initialize clipboard functionality\n  new ClipboardJS('.btn');\n  const form = $(\"#secretform\");\n\n  form.addEventListener('submit', function(e) {\n    e.preventDefault();\n\n    const formData = new FormData(form);\n\n    // Make AJAX request using fetch\n    fetch('/secret', {\n      method: 'POST',\n      body: formData\n    })\n    .then(response => {\n      if (!response.ok) {\n        throw new Error(`Request failed with status ${response.status}: ${response.statusText}`);\n      }\n      return response.json();\n    })\n    .then(data => {\n      // Show success state\n      setStyles($(\".success-encrypted\"), {\n        opacity: '1',\n        pointerEvents: 'auto',\n        visibility: 'visible'\n      });\n\n      // Hide form elements\n      setStyles($(\".encrypt\"), {\n        opacity: '0',\n        pointerEvents: 'none',\n        visibility: 'hidden'\n      });\n\n      setStyles($(\".ttl\"), {\n        opacity: '0',\n        pointerEvents: 'none',\n        visibility: 'hidden'\n      });\n\n      setStyles($(\".input-field\"), {\n        opacity: '0',\n        visibility: 'hidden',\n        pointerEvents: 'none'\n      });\n\n      showURL(data.token, data.filetoken, data.filename);\n    })\n    .catch(error => {\n      console.error(`An error occurred: ${error}`);\n      alert('An error occurred while creating the secret message.');\n    });\n  });\n});\n\nfunction showURL(token, filetoken, filename) {\n  const urlTextarea = $(\"#url\");\n\n  if (filetoken) {\n    urlTextarea.value = \n      `${window.location.origin}/getmsg?token=${encodeURIComponent(token)}&filetoken=${encodeURIComponent(filetoken)}&filename=${encodeURIComponent(filename)}`;\n    return;\n  }\n\n  urlTextarea.value = `${window.location.origin}/getmsg?token=${encodeURIComponent(token)}`;\n}\n"
  },
  {
    "path": "web/static/montserrat.css",
    "content": "@font-face {\n  font-family: Montserrat;\n  font-style: normal;\n  font-weight: 400;\n  src: local('Montserrat Regular'), local('Montserrat-Regular'), url('/static/fonts/montserrat-regular.ttf') format('truetype');\n}\n"
  },
  {
    "path": "web/static/robots.txt",
    "content": "User-agent: *\nDisallow: /"
  },
  {
    "path": "web/static/utils.js",
    "content": "/**\n * DOM Helper Functions\n * Provides convenient shortcuts for querySelector and querySelectorAll\n */\n\n// Returns the first element matching the CSS selector\nfunction $(selector) {\n  return document.querySelector(selector);\n}\n\n// Returns all elements matching the CSS selector\nfunction $$(selector) {\n  return document.querySelectorAll(selector);\n}\n"
  }
]