diff --git a/.dockerignore b/.dockerignore index 6c1d563..d4aba21 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,16 +1,16 @@ * -!components -!config -!globals -!listeners -!interactions -!model -!scheduled_tasks -!task -!utils -!go.mod -!go.sum +!proto +!heimdallr +!web-dashboard +!buf.lock +!buf.yaml +!buf.gen.yaml +!generate.go +!go.work +!go.work.sum !main.go +!package.json !rm_commands.go !start.sh +!Taskfile.yml !litestream.yml diff --git a/.fly/test.toml b/.fly/test.toml new file mode 100644 index 0000000..a6ae8ba --- /dev/null +++ b/.fly/test.toml @@ -0,0 +1,26 @@ +# fly.toml app configuration file generated for heimdallr-test on 2026-02-26T21:37:00+01:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'heimdallr-test' +primary_region = 'ord' + +[build] + +[[mounts]] + source = 'heimdallr' + destination = '/var/lib/heimdallr' + +[http_service] + internal_port = 8484 + force_https = true + auto_stop_machines = 'off' + auto_start_machines = true + min_machines_running = 0 + processes = ['app'] + +[[vm]] + memory = '512mb' + cpus = 1 + memory_mb = 512 diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 4f308e5..b967ea3 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -26,13 +26,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - + - uses: go-task/setup-task@v1 + - uses: oven-sh/setup-bun@v2 + with: + node-version: 24 - uses: actions/setup-go@v6 with: go-version-file: go.mod - name: Build - run: go build -v ./... + run: task build test: name: Test diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml new file mode 100644 index 0000000..b0c246e --- /dev/null +++ b/.github/workflows/fly-deploy.yml @@ -0,0 +1,18 @@ +# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ + +name: Fly Deploy +on: + push: + branches: + - main +jobs: + deploy: + name: Deploy app + runs-on: ubuntu-latest + concurrency: deploy-group # optional: ensure only one action runs at a time + steps: + - uses: actions/checkout@v4 + - uses: superfly/flyctl-actions/setup-flyctl@master + - run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/.gitignore b/.gitignore index c31dc00..b047516 100644 --- a/.gitignore +++ b/.gitignore @@ -33,9 +33,14 @@ go.work.sum # Heimdallr-specific files # Heimdallr binary -heimdallr +/heimdallr +/heimdallrbot +!/heimdallr/ # Heimdallr configuration file config.toml # Database file heimdallr.db pb_data/ + +# Embedded frontend build output +/rpcserver/frontend/ diff --git a/Dockerfile b/Dockerfile index a6f3f69..d72facc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,29 @@ +# syntax=docker/dockerfile:1.20.0 +FROM node:24-alpine AS frontend-builder + +WORKDIR /usr/src/app +COPY web-dashboard ./ +RUN npm install +RUN npm run build + + FROM golang:1.26 AS builder WORKDIR /usr/src/app -COPY go.mod go.sum ./ +COPY go.work go.work.sum ./ -RUN go mod download -COPY . . +COPY ./heimdallr ./heimdallr +COPY --from=frontend-builder /usr/src/app/dist ./heimdallr/rpcserver/frontend +COPY litestream.yml start.sh ./ -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags "-s -w" -o heimdallr . +RUN go mod download +RUN go generate github.com/NLLCommunity/heimdallr/... +RUN CGO_ENABLED=0 GOOS=linux \ + go build -a -installsuffix cgo -ldflags "-s -w" \ + -tags web -o heimdallrbot \ + github.com/NLLCommunity/heimdallr FROM alpine:3.23 @@ -21,8 +36,10 @@ VOLUME /var/lib/heimdallr RUN apk add --no-cache ca-certificates fuse3 sqlite tini COPY --from=litestream/litestream:0.5 /usr/local/bin/litestream /bin/litestream -COPY --from=builder /usr/src/app/heimdallr /usr/src/app/bin/heimdallr +COPY --from=builder /usr/src/app/heimdallrbot /usr/src/app/bin/heimdallr COPY --from=builder /usr/src/app/litestream.yml /usr/src/app/start.sh ./ +EXPOSE 8484 + ENTRYPOINT ["/sbin/tini", "--"] CMD ["./start.sh"] diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..cdd564e --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,42 @@ +# https://taskfile.dev + +version: "3" + +env: + GOPRIVATE: github.com/myrkvi/grem + GOTOOLCHAIN: auto + +tasks: + default: + desc: Build and run heimdallr + cmds: + - task: build + - task: run + run: + desc: Run heimdallr + preconditions: + - sh: test -f ./heimdallrbot{{exeExt}} + msg: "heimdallr binary not found, please run 'task build' first" + cmds: + - ./heimdallrbot{{exeExt}} + build: + desc: Build heimdallr binary + cmds: + - task: build-frontend + - task: build-backend + build-backend: + desc: Build heimdallr backend + cmds: + - go generate github.com/NLLCommunity/heimdallr/... + - > + go build -a -installsuffix cgo -ldflags "-s -w" + -tags web -o heimdallrbot{{exeExt}} + github.com/NLLCommunity/heimdallr + build-frontend: + desc: Build web dashboard and embed into rpcserver + dir: web-dashboard + cmds: + - bun install + - bun run build + - rm -rf ../heimdallr/rpcserver/frontend + - cp -rf dist ../heimdallr/rpcserver/frontend diff --git a/config.template.toml b/config.template.toml index e848c78..f708bbc 100644 --- a/config.template.toml +++ b/config.template.toml @@ -7,3 +7,11 @@ token = "INSERT_YOUR_TOKEN_HERE" # Discord bot token [dev_mode] enabled = true # Enable or disable developer mode guild_id = 0 # Guild ID to use for developer mode + +[web] +address = "localhost:8484" # RPC server address + +[dashboard] +base_url = "http://localhost:8484" # Web dashboard URL +# In production, use a TLS-terminating reverse proxy (e.g. nginx, Caddy) +# in front of the RPC server and set base_url to an https:// URL. diff --git a/go.mod b/go.mod deleted file mode 100644 index 09bbea2..0000000 --- a/go.mod +++ /dev/null @@ -1,58 +0,0 @@ -module github.com/NLLCommunity/heimdallr - -go 1.26.0 - -require ( - github.com/agnivade/levenshtein v1.2.1 - github.com/cbroglie/mustache v1.4.0 - github.com/disgoorg/disgo v0.19.2 - github.com/disgoorg/omit v1.0.0 - github.com/disgoorg/snowflake/v2 v2.0.3 - github.com/glebarez/sqlite v1.11.0 - github.com/google/uuid v1.6.0 - github.com/jellydator/ttlcache/v3 v3.4.0 - github.com/spf13/viper v1.21.0 - github.com/sqids/sqids-go v0.4.1 - github.com/stretchr/testify v1.11.1 - gorm.io/gorm v1.31.1 -) - -require golang.org/x/sync v0.19.0 // indirect - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076 // indirect - github.com/disgoorg/json/v2 v2.0.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/glebarez/go-sqlite v1.22.0 // indirect - github.com/go-viper/mapstructure/v2 v2.5.0 // indirect - github.com/gorilla/websocket v1.5.3 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/compress v1.18.4 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/ncruces/go-strftime v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/sagikazarmark/locafero v0.12.0 // indirect - github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect - github.com/spf13/afero v1.15.0 // indirect - github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/pflag v1.0.10 // indirect - github.com/stretchr/objx v0.5.3 // indirect - github.com/subosito/gotenv v1.6.0 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.48.0 // indirect - golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.67.7 // indirect - modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.45.0 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index 7fb8a20..0000000 --- a/go.sum +++ /dev/null @@ -1,143 +0,0 @@ -github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= -github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/cbroglie/mustache v1.4.0 h1:Azg0dVhxTml5me+7PsZ7WPrQq1Gkf3WApcHMjMprYoU= -github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9DtDsHo9iM= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= -github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/disgoorg/disgo v0.19.2 h1:9FTTnYZ5RnLX6oybPr18d9+ht2KxIMkG/+HY0ADqTbM= -github.com/disgoorg/disgo v0.19.2/go.mod h1:rLCcf3vnlyfOTGw8ksVmq5UE5CMzBA0eeA9oeZ+N0x4= -github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076 h1:GN4w6H8zlH/kFRFnzjk+4Kg9KEUJ+jY0e4MZaGlFKh8= -github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076/go.mod h1:OreAC3hpabr39bMVA+jwOVDq1EUPXH5A0XUBiZaDI1Y= -github.com/disgoorg/json/v2 v2.0.0 h1:U16yy/ARK7/aEpzjjqK1b/KaqqGHozUdeVw/DViEzQI= -github.com/disgoorg/json/v2 v2.0.0/go.mod h1:jZTBC0nIE1WeetSEI3/Dka8g+qglb4FPVmp5I5HpEfI= -github.com/disgoorg/omit v1.0.0 h1:y0LkVUOyUHT8ZlnhIAeOZEA22UYykeysK8bLJ0SfT78= -github.com/disgoorg/omit v1.0.0/go.mod h1:RTmSARkf6PWT/UckwI0bV8XgWkWQoPppaT01rYKLcFQ= -github.com/disgoorg/snowflake/v2 v2.0.3 h1:3B+PpFjr7j4ad7oeJu4RlQ+nYOTadsKapJIzgvSI2Ro= -github.com/disgoorg/snowflake/v2 v2.0.3/go.mod h1:W6r7NUA7DwfZLwr00km6G4UnZ0zcoLBRufhkFWgAc4c= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= -github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= -github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= -github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= -github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= -github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= -github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= -github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= -github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= -github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= -github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= -github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxEmTbaqt1hkJ/t6skqEGYiMag343ucI= -github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= -github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= -github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= -github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= -github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= -github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= -github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= -github.com/sqids/sqids-go v0.4.1 h1:eQKYzmAZbLlRwHeHYPF35QhgxwZHLnlmVj9AkIj/rrw= -github.com/sqids/sqids-go v0.4.1/go.mod h1:EMwHuPQgSNFS0A49jESTfIQS+066XQTVhukrzEPScl8= -github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= -github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o= -golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= -gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= -modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= -modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc= -modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM= -modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= -modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= -modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= -modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE= -modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= -modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= -modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= -modernc.org/libc v1.67.7 h1:H+gYQw2PyidyxwxQsGTwQw6+6H+xUk+plvOKW7+d3TI= -modernc.org/libc v1.67.7/go.mod h1:UjCSJFl2sYbJbReVQeVpq/MgzlbmDM4cRHIYFelnaDk= -modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= -modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= -modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= -modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= -modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= -modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= -modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.45.0 h1:r51cSGzKpbptxnby+EIIz5fop4VuE4qFoVEjNvWoObs= -modernc.org/sqlite v1.45.0/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA= -modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= -modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/heimdallr/buf.gen.yaml b/heimdallr/buf.gen.yaml new file mode 100644 index 0000000..8a35e70 --- /dev/null +++ b/heimdallr/buf.gen.yaml @@ -0,0 +1,26 @@ +version: v2 +plugins: + #- local: protoc-gen-go + - remote: buf.build/protocolbuffers/go:v1.36.11 + out: gen + opt: paths=source_relative + #- local: protoc-gen-connect-go + - remote: buf.build/connectrpc/go:v1.19.1 + out: gen + opt: + - paths=source_relative + - simple + #- local: protoc-gen-es + - remote: buf.build/bufbuild/es:v2.11.0 + out: ../web-dashboard/src/gen + include_imports: true + opt: target=ts + +managed: + enabled: true + override: + - file_option: go_package_prefix + value: github.com/NLLCommunity/heimdallr/gen + disable: + - file_option: go_package + module: buf.build/bufbuild/protovalidate diff --git a/heimdallr/buf.lock b/heimdallr/buf.lock new file mode 100644 index 0000000..d15a117 --- /dev/null +++ b/heimdallr/buf.lock @@ -0,0 +1,6 @@ +# Generated by buf. DO NOT EDIT. +version: v2 +deps: + - name: buf.build/bufbuild/protovalidate + commit: 80ab13bee0bf4272b6161a72bf7034e0 + digest: b5:1aa6a965be5d02d64e1d81954fa2e78ef9d1e33a0c30f92bc2626039006a94deb3a5b05f14ed8893f5c3ffce444ac008f7e968188ad225c4c29c813aa5f2daa1 diff --git a/heimdallr/buf.yaml b/heimdallr/buf.yaml new file mode 100644 index 0000000..081825e --- /dev/null +++ b/heimdallr/buf.yaml @@ -0,0 +1,12 @@ +# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +deps: + - buf.build/bufbuild/protovalidate +modules: + - path: proto +lint: + use: + - STANDARD +breaking: + use: + - FILE diff --git a/config/config.go b/heimdallr/config/config.go similarity index 90% rename from config/config.go rename to heimdallr/config/config.go index deaff43..dbb5f63 100644 --- a/config/config.go +++ b/heimdallr/config/config.go @@ -31,6 +31,10 @@ func init() { viper.SetDefault("dev_mode.enabled", false) viper.SetDefault("dev_mode.guild_id", 0) + viper.SetDefault("web.address", ":8484") + + viper.SetDefault("dashboard.base_url", "http://localhost:8484") + viper.AutomaticEnv() if err := viper.ReadInConfig(); err != nil { diff --git a/config/config_test.go b/heimdallr/config/config_test.go similarity index 100% rename from config/config_test.go rename to heimdallr/config/config_test.go diff --git a/heimdallr/gen/greet/v1/greet.pb.go b/heimdallr/gen/greet/v1/greet.pb.go new file mode 100644 index 0000000..fed4a52 --- /dev/null +++ b/heimdallr/gen/greet/v1/greet.pb.go @@ -0,0 +1,176 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: greet/v1/greet.proto + +package greetv1 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GreetRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GreetRequest) Reset() { + *x = GreetRequest{} + mi := &file_greet_v1_greet_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GreetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetRequest) ProtoMessage() {} + +func (x *GreetRequest) ProtoReflect() protoreflect.Message { + mi := &file_greet_v1_greet_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetRequest.ProtoReflect.Descriptor instead. +func (*GreetRequest) Descriptor() ([]byte, []int) { + return file_greet_v1_greet_proto_rawDescGZIP(), []int{0} +} + +func (x *GreetRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GreetResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GreetResponse) Reset() { + *x = GreetResponse{} + mi := &file_greet_v1_greet_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GreetResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetResponse) ProtoMessage() {} + +func (x *GreetResponse) ProtoReflect() protoreflect.Message { + mi := &file_greet_v1_greet_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetResponse.ProtoReflect.Descriptor instead. +func (*GreetResponse) Descriptor() ([]byte, []int) { + return file_greet_v1_greet_proto_rawDescGZIP(), []int{1} +} + +func (x *GreetResponse) GetGreeting() string { + if x != nil { + return x.Greeting + } + return "" +} + +var File_greet_v1_greet_proto protoreflect.FileDescriptor + +const file_greet_v1_greet_proto_rawDesc = "" + + "\n" + + "\x14greet/v1/greet.proto\x12\bgreet.v1\x1a\x1bbuf/validate/validate.proto\"-\n" + + "\fGreetRequest\x12\x1d\n" + + "\x04name\x18\x01 \x01(\tB\t\xbaH\x06r\x04\x10\x01\x182R\x04name\"+\n" + + "\rGreetResponse\x12\x1a\n" + + "\bgreeting\x18\x01 \x01(\tR\bgreeting2J\n" + + "\fGreetService\x12:\n" + + "\x05Greet\x12\x16.greet.v1.GreetRequest\x1a\x17.greet.v1.GreetResponse\"\x00B\x93\x01\n" + + "\fcom.greet.v1B\n" + + "GreetProtoP\x01Z6github.com/NLLCommunity/heimdallr/gen/greet/v1;greetv1\xa2\x02\x03GXX\xaa\x02\bGreet.V1\xca\x02\bGreet\\V1\xe2\x02\x14Greet\\V1\\GPBMetadata\xea\x02\tGreet::V1b\x06proto3" + +var ( + file_greet_v1_greet_proto_rawDescOnce sync.Once + file_greet_v1_greet_proto_rawDescData []byte +) + +func file_greet_v1_greet_proto_rawDescGZIP() []byte { + file_greet_v1_greet_proto_rawDescOnce.Do(func() { + file_greet_v1_greet_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_greet_v1_greet_proto_rawDesc), len(file_greet_v1_greet_proto_rawDesc))) + }) + return file_greet_v1_greet_proto_rawDescData +} + +var file_greet_v1_greet_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_greet_v1_greet_proto_goTypes = []any{ + (*GreetRequest)(nil), // 0: greet.v1.GreetRequest + (*GreetResponse)(nil), // 1: greet.v1.GreetResponse +} +var file_greet_v1_greet_proto_depIdxs = []int32{ + 0, // 0: greet.v1.GreetService.Greet:input_type -> greet.v1.GreetRequest + 1, // 1: greet.v1.GreetService.Greet:output_type -> greet.v1.GreetResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_greet_v1_greet_proto_init() } +func file_greet_v1_greet_proto_init() { + if File_greet_v1_greet_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_greet_v1_greet_proto_rawDesc), len(file_greet_v1_greet_proto_rawDesc)), + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_greet_v1_greet_proto_goTypes, + DependencyIndexes: file_greet_v1_greet_proto_depIdxs, + MessageInfos: file_greet_v1_greet_proto_msgTypes, + }.Build() + File_greet_v1_greet_proto = out.File + file_greet_v1_greet_proto_goTypes = nil + file_greet_v1_greet_proto_depIdxs = nil +} diff --git a/heimdallr/gen/greet/v1/greetv1connect/greet.connect.go b/heimdallr/gen/greet/v1/greetv1connect/greet.connect.go new file mode 100644 index 0000000..54db5d2 --- /dev/null +++ b/heimdallr/gen/greet/v1/greetv1connect/greet.connect.go @@ -0,0 +1,112 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: greet/v1/greet.proto + +package greetv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/greet/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // GreetServiceName is the fully-qualified name of the GreetService service. + GreetServiceName = "greet.v1.GreetService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GreetServiceGreetProcedure is the fully-qualified name of the GreetService's Greet RPC. + GreetServiceGreetProcedure = "/greet.v1.GreetService/Greet" +) + +// GreetServiceClient is a client for the greet.v1.GreetService service. +type GreetServiceClient interface { + Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) +} + +// NewGreetServiceClient constructs a client for the greet.v1.GreetService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewGreetServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GreetServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + greetServiceMethods := v1.File_greet_v1_greet_proto.Services().ByName("GreetService").Methods() + return &greetServiceClient{ + greet: connect.NewClient[v1.GreetRequest, v1.GreetResponse]( + httpClient, + baseURL+GreetServiceGreetProcedure, + connect.WithSchema(greetServiceMethods.ByName("Greet")), + connect.WithClientOptions(opts...), + ), + } +} + +// greetServiceClient implements GreetServiceClient. +type greetServiceClient struct { + greet *connect.Client[v1.GreetRequest, v1.GreetResponse] +} + +// Greet calls greet.v1.GreetService.Greet. +func (c *greetServiceClient) Greet(ctx context.Context, req *v1.GreetRequest) (*v1.GreetResponse, error) { + response, err := c.greet.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GreetServiceHandler is an implementation of the greet.v1.GreetService service. +type GreetServiceHandler interface { + Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) +} + +// NewGreetServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewGreetServiceHandler(svc GreetServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + greetServiceMethods := v1.File_greet_v1_greet_proto.Services().ByName("GreetService").Methods() + greetServiceGreetHandler := connect.NewUnaryHandlerSimple( + GreetServiceGreetProcedure, + svc.Greet, + connect.WithSchema(greetServiceMethods.ByName("Greet")), + connect.WithHandlerOptions(opts...), + ) + return "/greet.v1.GreetService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case GreetServiceGreetProcedure: + greetServiceGreetHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedGreetServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedGreetServiceHandler struct{} + +func (UnimplementedGreetServiceHandler) Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("greet.v1.GreetService.Greet is not implemented")) +} diff --git a/heimdallr/gen/heimdallr/v1/auth.pb.go b/heimdallr/gen/heimdallr/v1/auth.pb.go new file mode 100644 index 0000000..be4ecd3 --- /dev/null +++ b/heimdallr/gen/heimdallr/v1/auth.pb.go @@ -0,0 +1,651 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: heimdallr/v1/auth.proto + +package heimdallrv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type User struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *User) Reset() { + *x = User{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *User) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +type Guild struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Icon string `protobuf:"bytes,3,opt,name=icon,proto3" json:"icon,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Guild) Reset() { + *x = Guild{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Guild) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Guild) ProtoMessage() {} + +func (x *Guild) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Guild.ProtoReflect.Descriptor instead. +func (*Guild) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{1} +} + +func (x *Guild) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Guild) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Guild) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +type GetLoginURLRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetLoginURLRequest) Reset() { + *x = GetLoginURLRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetLoginURLRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLoginURLRequest) ProtoMessage() {} + +func (x *GetLoginURLRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLoginURLRequest.ProtoReflect.Descriptor instead. +func (*GetLoginURLRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{2} +} + +type GetLoginURLResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetLoginURLResponse) Reset() { + *x = GetLoginURLResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetLoginURLResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLoginURLResponse) ProtoMessage() {} + +func (x *GetLoginURLResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLoginURLResponse.ProtoReflect.Descriptor instead. +func (*GetLoginURLResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{3} +} + +func (x *GetLoginURLResponse) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type ExchangeCodeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExchangeCodeRequest) Reset() { + *x = ExchangeCodeRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExchangeCodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExchangeCodeRequest) ProtoMessage() {} + +func (x *ExchangeCodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExchangeCodeRequest.ProtoReflect.Descriptor instead. +func (*ExchangeCodeRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{4} +} + +func (x *ExchangeCodeRequest) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +type ExchangeCodeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExchangeCodeResponse) Reset() { + *x = ExchangeCodeResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExchangeCodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExchangeCodeResponse) ProtoMessage() {} + +func (x *ExchangeCodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExchangeCodeResponse.ProtoReflect.Descriptor instead. +func (*ExchangeCodeResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{5} +} + +func (x *ExchangeCodeResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type GetCurrentUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCurrentUserRequest) Reset() { + *x = GetCurrentUserRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCurrentUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentUserRequest) ProtoMessage() {} + +func (x *GetCurrentUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCurrentUserRequest.ProtoReflect.Descriptor instead. +func (*GetCurrentUserRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{6} +} + +type GetCurrentUserResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCurrentUserResponse) Reset() { + *x = GetCurrentUserResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCurrentUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentUserResponse) ProtoMessage() {} + +func (x *GetCurrentUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCurrentUserResponse.ProtoReflect.Descriptor instead. +func (*GetCurrentUserResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{7} +} + +func (x *GetCurrentUserResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type ListGuildsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListGuildsRequest) Reset() { + *x = ListGuildsRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListGuildsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListGuildsRequest) ProtoMessage() {} + +func (x *ListGuildsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListGuildsRequest.ProtoReflect.Descriptor instead. +func (*ListGuildsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{8} +} + +type ListGuildsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Guilds []*Guild `protobuf:"bytes,1,rep,name=guilds,proto3" json:"guilds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListGuildsResponse) Reset() { + *x = ListGuildsResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListGuildsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListGuildsResponse) ProtoMessage() {} + +func (x *ListGuildsResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListGuildsResponse.ProtoReflect.Descriptor instead. +func (*ListGuildsResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{9} +} + +func (x *ListGuildsResponse) GetGuilds() []*Guild { + if x != nil { + return x.Guilds + } + return nil +} + +type LogoutRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogoutRequest) Reset() { + *x = LogoutRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutRequest) ProtoMessage() {} + +func (x *LogoutRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. +func (*LogoutRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{10} +} + +type LogoutResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogoutResponse) Reset() { + *x = LogoutResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutResponse) ProtoMessage() {} + +func (x *LogoutResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead. +func (*LogoutResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{11} +} + +var File_heimdallr_v1_auth_proto protoreflect.FileDescriptor + +const file_heimdallr_v1_auth_proto_rawDesc = "" + + "\n" + + "\x17heimdallr/v1/auth.proto\x12\fheimdallr.v1\"J\n" + + "\x04User\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" + + "\busername\x18\x02 \x01(\tR\busername\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\"?\n" + + "\x05Guild\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04icon\x18\x03 \x01(\tR\x04icon\"\x14\n" + + "\x12GetLoginURLRequest\"'\n" + + "\x13GetLoginURLResponse\x12\x10\n" + + "\x03url\x18\x01 \x01(\tR\x03url\")\n" + + "\x13ExchangeCodeRequest\x12\x12\n" + + "\x04code\x18\x01 \x01(\tR\x04code\">\n" + + "\x14ExchangeCodeResponse\x12&\n" + + "\x04user\x18\x02 \x01(\v2\x12.heimdallr.v1.UserR\x04user\"\x17\n" + + "\x15GetCurrentUserRequest\"@\n" + + "\x16GetCurrentUserResponse\x12&\n" + + "\x04user\x18\x01 \x01(\v2\x12.heimdallr.v1.UserR\x04user\"\x13\n" + + "\x11ListGuildsRequest\"A\n" + + "\x12ListGuildsResponse\x12+\n" + + "\x06guilds\x18\x01 \x03(\v2\x13.heimdallr.v1.GuildR\x06guilds\"\x0f\n" + + "\rLogoutRequest\"\x10\n" + + "\x0eLogoutResponse2\xab\x03\n" + + "\vAuthService\x12R\n" + + "\vGetLoginURL\x12 .heimdallr.v1.GetLoginURLRequest\x1a!.heimdallr.v1.GetLoginURLResponse\x12U\n" + + "\fExchangeCode\x12!.heimdallr.v1.ExchangeCodeRequest\x1a\".heimdallr.v1.ExchangeCodeResponse\x12[\n" + + "\x0eGetCurrentUser\x12#.heimdallr.v1.GetCurrentUserRequest\x1a$.heimdallr.v1.GetCurrentUserResponse\x12O\n" + + "\n" + + "ListGuilds\x12\x1f.heimdallr.v1.ListGuildsRequest\x1a .heimdallr.v1.ListGuildsResponse\x12C\n" + + "\x06Logout\x12\x1b.heimdallr.v1.LogoutRequest\x1a\x1c.heimdallr.v1.LogoutResponseB\xae\x01\n" + + "\x10com.heimdallr.v1B\tAuthProtoP\x01Z>github.com/NLLCommunity/heimdallr/gen/heimdallr/v1;heimdallrv1\xa2\x02\x03HXX\xaa\x02\fHeimdallr.V1\xca\x02\fHeimdallr\\V1\xe2\x02\x18Heimdallr\\V1\\GPBMetadata\xea\x02\rHeimdallr::V1b\x06proto3" + +var ( + file_heimdallr_v1_auth_proto_rawDescOnce sync.Once + file_heimdallr_v1_auth_proto_rawDescData []byte +) + +func file_heimdallr_v1_auth_proto_rawDescGZIP() []byte { + file_heimdallr_v1_auth_proto_rawDescOnce.Do(func() { + file_heimdallr_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_heimdallr_v1_auth_proto_rawDesc), len(file_heimdallr_v1_auth_proto_rawDesc))) + }) + return file_heimdallr_v1_auth_proto_rawDescData +} + +var file_heimdallr_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_heimdallr_v1_auth_proto_goTypes = []any{ + (*User)(nil), // 0: heimdallr.v1.User + (*Guild)(nil), // 1: heimdallr.v1.Guild + (*GetLoginURLRequest)(nil), // 2: heimdallr.v1.GetLoginURLRequest + (*GetLoginURLResponse)(nil), // 3: heimdallr.v1.GetLoginURLResponse + (*ExchangeCodeRequest)(nil), // 4: heimdallr.v1.ExchangeCodeRequest + (*ExchangeCodeResponse)(nil), // 5: heimdallr.v1.ExchangeCodeResponse + (*GetCurrentUserRequest)(nil), // 6: heimdallr.v1.GetCurrentUserRequest + (*GetCurrentUserResponse)(nil), // 7: heimdallr.v1.GetCurrentUserResponse + (*ListGuildsRequest)(nil), // 8: heimdallr.v1.ListGuildsRequest + (*ListGuildsResponse)(nil), // 9: heimdallr.v1.ListGuildsResponse + (*LogoutRequest)(nil), // 10: heimdallr.v1.LogoutRequest + (*LogoutResponse)(nil), // 11: heimdallr.v1.LogoutResponse +} +var file_heimdallr_v1_auth_proto_depIdxs = []int32{ + 0, // 0: heimdallr.v1.ExchangeCodeResponse.user:type_name -> heimdallr.v1.User + 0, // 1: heimdallr.v1.GetCurrentUserResponse.user:type_name -> heimdallr.v1.User + 1, // 2: heimdallr.v1.ListGuildsResponse.guilds:type_name -> heimdallr.v1.Guild + 2, // 3: heimdallr.v1.AuthService.GetLoginURL:input_type -> heimdallr.v1.GetLoginURLRequest + 4, // 4: heimdallr.v1.AuthService.ExchangeCode:input_type -> heimdallr.v1.ExchangeCodeRequest + 6, // 5: heimdallr.v1.AuthService.GetCurrentUser:input_type -> heimdallr.v1.GetCurrentUserRequest + 8, // 6: heimdallr.v1.AuthService.ListGuilds:input_type -> heimdallr.v1.ListGuildsRequest + 10, // 7: heimdallr.v1.AuthService.Logout:input_type -> heimdallr.v1.LogoutRequest + 3, // 8: heimdallr.v1.AuthService.GetLoginURL:output_type -> heimdallr.v1.GetLoginURLResponse + 5, // 9: heimdallr.v1.AuthService.ExchangeCode:output_type -> heimdallr.v1.ExchangeCodeResponse + 7, // 10: heimdallr.v1.AuthService.GetCurrentUser:output_type -> heimdallr.v1.GetCurrentUserResponse + 9, // 11: heimdallr.v1.AuthService.ListGuilds:output_type -> heimdallr.v1.ListGuildsResponse + 11, // 12: heimdallr.v1.AuthService.Logout:output_type -> heimdallr.v1.LogoutResponse + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_heimdallr_v1_auth_proto_init() } +func file_heimdallr_v1_auth_proto_init() { + if File_heimdallr_v1_auth_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_heimdallr_v1_auth_proto_rawDesc), len(file_heimdallr_v1_auth_proto_rawDesc)), + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_heimdallr_v1_auth_proto_goTypes, + DependencyIndexes: file_heimdallr_v1_auth_proto_depIdxs, + MessageInfos: file_heimdallr_v1_auth_proto_msgTypes, + }.Build() + File_heimdallr_v1_auth_proto = out.File + file_heimdallr_v1_auth_proto_goTypes = nil + file_heimdallr_v1_auth_proto_depIdxs = nil +} diff --git a/heimdallr/gen/heimdallr/v1/guild_settings.pb.go b/heimdallr/gen/heimdallr/v1/guild_settings.pb.go new file mode 100644 index 0000000..b936723 --- /dev/null +++ b/heimdallr/gen/heimdallr/v1/guild_settings.pb.go @@ -0,0 +1,2001 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: heimdallr/v1/guild_settings.proto + +package heimdallrv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ModChannel +type GetModChannelRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetModChannelRequest) Reset() { + *x = GetModChannelRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetModChannelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModChannelRequest) ProtoMessage() {} + +func (x *GetModChannelRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModChannelRequest.ProtoReflect.Descriptor instead. +func (*GetModChannelRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{0} +} + +func (x *GetModChannelRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateModChannelRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *ModChannelSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateModChannelRequest) Reset() { + *x = UpdateModChannelRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateModChannelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModChannelRequest) ProtoMessage() {} + +func (x *UpdateModChannelRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModChannelRequest.ProtoReflect.Descriptor instead. +func (*UpdateModChannelRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateModChannelRequest) GetSettings() *ModChannelSettings { + if x != nil { + return x.Settings + } + return nil +} + +type ModChannelSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ModeratorChannel string `protobuf:"bytes,2,opt,name=moderator_channel,json=moderatorChannel,proto3" json:"moderator_channel,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ModChannelSettings) Reset() { + *x = ModChannelSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ModChannelSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModChannelSettings) ProtoMessage() {} + +func (x *ModChannelSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModChannelSettings.ProtoReflect.Descriptor instead. +func (*ModChannelSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{2} +} + +func (x *ModChannelSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *ModChannelSettings) GetModeratorChannel() string { + if x != nil { + return x.ModeratorChannel + } + return "" +} + +// InfractionSettings +type GetInfractionSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInfractionSettingsRequest) Reset() { + *x = GetInfractionSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInfractionSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfractionSettingsRequest) ProtoMessage() {} + +func (x *GetInfractionSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfractionSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetInfractionSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{3} +} + +func (x *GetInfractionSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateInfractionSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *InfractionSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateInfractionSettingsRequest) Reset() { + *x = UpdateInfractionSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateInfractionSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateInfractionSettingsRequest) ProtoMessage() {} + +func (x *UpdateInfractionSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateInfractionSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateInfractionSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateInfractionSettingsRequest) GetSettings() *InfractionSettings { + if x != nil { + return x.Settings + } + return nil +} + +type InfractionSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + HalfLifeDays float64 `protobuf:"fixed64,2,opt,name=half_life_days,json=halfLifeDays,proto3" json:"half_life_days,omitempty"` + NotifyOnWarnedUserJoin bool `protobuf:"varint,3,opt,name=notify_on_warned_user_join,json=notifyOnWarnedUserJoin,proto3" json:"notify_on_warned_user_join,omitempty"` + NotifyWarnSeverityThreshold float64 `protobuf:"fixed64,4,opt,name=notify_warn_severity_threshold,json=notifyWarnSeverityThreshold,proto3" json:"notify_warn_severity_threshold,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InfractionSettings) Reset() { + *x = InfractionSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InfractionSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfractionSettings) ProtoMessage() {} + +func (x *InfractionSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InfractionSettings.ProtoReflect.Descriptor instead. +func (*InfractionSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{5} +} + +func (x *InfractionSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *InfractionSettings) GetHalfLifeDays() float64 { + if x != nil { + return x.HalfLifeDays + } + return 0 +} + +func (x *InfractionSettings) GetNotifyOnWarnedUserJoin() bool { + if x != nil { + return x.NotifyOnWarnedUserJoin + } + return false +} + +func (x *InfractionSettings) GetNotifyWarnSeverityThreshold() float64 { + if x != nil { + return x.NotifyWarnSeverityThreshold + } + return 0 +} + +// GatekeepSettings +type GetGatekeepSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetGatekeepSettingsRequest) Reset() { + *x = GetGatekeepSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetGatekeepSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetGatekeepSettingsRequest) ProtoMessage() {} + +func (x *GetGatekeepSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetGatekeepSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetGatekeepSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{6} +} + +func (x *GetGatekeepSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateGatekeepSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *GatekeepSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateGatekeepSettingsRequest) Reset() { + *x = UpdateGatekeepSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateGatekeepSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateGatekeepSettingsRequest) ProtoMessage() {} + +func (x *UpdateGatekeepSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateGatekeepSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateGatekeepSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateGatekeepSettingsRequest) GetSettings() *GatekeepSettings { + if x != nil { + return x.Settings + } + return nil +} + +type GatekeepSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + PendingRole string `protobuf:"bytes,3,opt,name=pending_role,json=pendingRole,proto3" json:"pending_role,omitempty"` + ApprovedRole string `protobuf:"bytes,4,opt,name=approved_role,json=approvedRole,proto3" json:"approved_role,omitempty"` + AddPendingRoleOnJoin bool `protobuf:"varint,5,opt,name=add_pending_role_on_join,json=addPendingRoleOnJoin,proto3" json:"add_pending_role_on_join,omitempty"` + ApprovedMessage string `protobuf:"bytes,6,opt,name=approved_message,json=approvedMessage,proto3" json:"approved_message,omitempty"` + ApprovedMessageV2 bool `protobuf:"varint,7,opt,name=approved_message_v2,json=approvedMessageV2,proto3" json:"approved_message_v2,omitempty"` + ApprovedMessageV2Json string `protobuf:"bytes,8,opt,name=approved_message_v2_json,json=approvedMessageV2Json,proto3" json:"approved_message_v2_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GatekeepSettings) Reset() { + *x = GatekeepSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GatekeepSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GatekeepSettings) ProtoMessage() {} + +func (x *GatekeepSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GatekeepSettings.ProtoReflect.Descriptor instead. +func (*GatekeepSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{8} +} + +func (x *GatekeepSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *GatekeepSettings) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *GatekeepSettings) GetPendingRole() string { + if x != nil { + return x.PendingRole + } + return "" +} + +func (x *GatekeepSettings) GetApprovedRole() string { + if x != nil { + return x.ApprovedRole + } + return "" +} + +func (x *GatekeepSettings) GetAddPendingRoleOnJoin() bool { + if x != nil { + return x.AddPendingRoleOnJoin + } + return false +} + +func (x *GatekeepSettings) GetApprovedMessage() string { + if x != nil { + return x.ApprovedMessage + } + return "" +} + +func (x *GatekeepSettings) GetApprovedMessageV2() bool { + if x != nil { + return x.ApprovedMessageV2 + } + return false +} + +func (x *GatekeepSettings) GetApprovedMessageV2Json() string { + if x != nil { + return x.ApprovedMessageV2Json + } + return "" +} + +// JoinLeaveSettings +type GetJoinLeaveSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetJoinLeaveSettingsRequest) Reset() { + *x = GetJoinLeaveSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetJoinLeaveSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJoinLeaveSettingsRequest) ProtoMessage() {} + +func (x *GetJoinLeaveSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJoinLeaveSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetJoinLeaveSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{9} +} + +func (x *GetJoinLeaveSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateJoinLeaveSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *JoinLeaveSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateJoinLeaveSettingsRequest) Reset() { + *x = UpdateJoinLeaveSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateJoinLeaveSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateJoinLeaveSettingsRequest) ProtoMessage() {} + +func (x *UpdateJoinLeaveSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateJoinLeaveSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateJoinLeaveSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateJoinLeaveSettingsRequest) GetSettings() *JoinLeaveSettings { + if x != nil { + return x.Settings + } + return nil +} + +type JoinLeaveSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + JoinMessageEnabled bool `protobuf:"varint,2,opt,name=join_message_enabled,json=joinMessageEnabled,proto3" json:"join_message_enabled,omitempty"` + JoinMessage string `protobuf:"bytes,3,opt,name=join_message,json=joinMessage,proto3" json:"join_message,omitempty"` + LeaveMessageEnabled bool `protobuf:"varint,4,opt,name=leave_message_enabled,json=leaveMessageEnabled,proto3" json:"leave_message_enabled,omitempty"` + LeaveMessage string `protobuf:"bytes,5,opt,name=leave_message,json=leaveMessage,proto3" json:"leave_message,omitempty"` + Channel string `protobuf:"bytes,6,opt,name=channel,proto3" json:"channel,omitempty"` + JoinMessageV2 bool `protobuf:"varint,7,opt,name=join_message_v2,json=joinMessageV2,proto3" json:"join_message_v2,omitempty"` + JoinMessageV2Json string `protobuf:"bytes,8,opt,name=join_message_v2_json,json=joinMessageV2Json,proto3" json:"join_message_v2_json,omitempty"` + LeaveMessageV2 bool `protobuf:"varint,9,opt,name=leave_message_v2,json=leaveMessageV2,proto3" json:"leave_message_v2,omitempty"` + LeaveMessageV2Json string `protobuf:"bytes,10,opt,name=leave_message_v2_json,json=leaveMessageV2Json,proto3" json:"leave_message_v2_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JoinLeaveSettings) Reset() { + *x = JoinLeaveSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JoinLeaveSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JoinLeaveSettings) ProtoMessage() {} + +func (x *JoinLeaveSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JoinLeaveSettings.ProtoReflect.Descriptor instead. +func (*JoinLeaveSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{11} +} + +func (x *JoinLeaveSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *JoinLeaveSettings) GetJoinMessageEnabled() bool { + if x != nil { + return x.JoinMessageEnabled + } + return false +} + +func (x *JoinLeaveSettings) GetJoinMessage() string { + if x != nil { + return x.JoinMessage + } + return "" +} + +func (x *JoinLeaveSettings) GetLeaveMessageEnabled() bool { + if x != nil { + return x.LeaveMessageEnabled + } + return false +} + +func (x *JoinLeaveSettings) GetLeaveMessage() string { + if x != nil { + return x.LeaveMessage + } + return "" +} + +func (x *JoinLeaveSettings) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *JoinLeaveSettings) GetJoinMessageV2() bool { + if x != nil { + return x.JoinMessageV2 + } + return false +} + +func (x *JoinLeaveSettings) GetJoinMessageV2Json() string { + if x != nil { + return x.JoinMessageV2Json + } + return "" +} + +func (x *JoinLeaveSettings) GetLeaveMessageV2() bool { + if x != nil { + return x.LeaveMessageV2 + } + return false +} + +func (x *JoinLeaveSettings) GetLeaveMessageV2Json() string { + if x != nil { + return x.LeaveMessageV2Json + } + return "" +} + +// AntiSpamSettings +type GetAntiSpamSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAntiSpamSettingsRequest) Reset() { + *x = GetAntiSpamSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAntiSpamSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAntiSpamSettingsRequest) ProtoMessage() {} + +func (x *GetAntiSpamSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAntiSpamSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetAntiSpamSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{12} +} + +func (x *GetAntiSpamSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateAntiSpamSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *AntiSpamSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateAntiSpamSettingsRequest) Reset() { + *x = UpdateAntiSpamSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateAntiSpamSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAntiSpamSettingsRequest) ProtoMessage() {} + +func (x *UpdateAntiSpamSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAntiSpamSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateAntiSpamSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{13} +} + +func (x *UpdateAntiSpamSettingsRequest) GetSettings() *AntiSpamSettings { + if x != nil { + return x.Settings + } + return nil +} + +type AntiSpamSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + Count int32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` + CooldownSeconds int32 `protobuf:"varint,4,opt,name=cooldown_seconds,json=cooldownSeconds,proto3" json:"cooldown_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AntiSpamSettings) Reset() { + *x = AntiSpamSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AntiSpamSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AntiSpamSettings) ProtoMessage() {} + +func (x *AntiSpamSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AntiSpamSettings.ProtoReflect.Descriptor instead. +func (*AntiSpamSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{14} +} + +func (x *AntiSpamSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *AntiSpamSettings) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *AntiSpamSettings) GetCount() int32 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *AntiSpamSettings) GetCooldownSeconds() int32 { + if x != nil { + return x.CooldownSeconds + } + return 0 +} + +// BanFooterSettings +type GetBanFooterSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetBanFooterSettingsRequest) Reset() { + *x = GetBanFooterSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetBanFooterSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBanFooterSettingsRequest) ProtoMessage() {} + +func (x *GetBanFooterSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBanFooterSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetBanFooterSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBanFooterSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateBanFooterSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *BanFooterSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateBanFooterSettingsRequest) Reset() { + *x = UpdateBanFooterSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateBanFooterSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBanFooterSettingsRequest) ProtoMessage() {} + +func (x *UpdateBanFooterSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateBanFooterSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateBanFooterSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{16} +} + +func (x *UpdateBanFooterSettingsRequest) GetSettings() *BanFooterSettings { + if x != nil { + return x.Settings + } + return nil +} + +type BanFooterSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Footer string `protobuf:"bytes,2,opt,name=footer,proto3" json:"footer,omitempty"` + AlwaysSend bool `protobuf:"varint,3,opt,name=always_send,json=alwaysSend,proto3" json:"always_send,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BanFooterSettings) Reset() { + *x = BanFooterSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BanFooterSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BanFooterSettings) ProtoMessage() {} + +func (x *BanFooterSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BanFooterSettings.ProtoReflect.Descriptor instead. +func (*BanFooterSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{17} +} + +func (x *BanFooterSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *BanFooterSettings) GetFooter() string { + if x != nil { + return x.Footer + } + return "" +} + +func (x *BanFooterSettings) GetAlwaysSend() bool { + if x != nil { + return x.AlwaysSend + } + return false +} + +// ModmailSettings +type GetModmailSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetModmailSettingsRequest) Reset() { + *x = GetModmailSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetModmailSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModmailSettingsRequest) ProtoMessage() {} + +func (x *GetModmailSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModmailSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetModmailSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{18} +} + +func (x *GetModmailSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateModmailSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *ModmailSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateModmailSettingsRequest) Reset() { + *x = UpdateModmailSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateModmailSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModmailSettingsRequest) ProtoMessage() {} + +func (x *UpdateModmailSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModmailSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateModmailSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{19} +} + +func (x *UpdateModmailSettingsRequest) GetSettings() *ModmailSettings { + if x != nil { + return x.Settings + } + return nil +} + +type ModmailSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ReportThreadsChannel string `protobuf:"bytes,2,opt,name=report_threads_channel,json=reportThreadsChannel,proto3" json:"report_threads_channel,omitempty"` + ReportNotificationChannel string `protobuf:"bytes,3,opt,name=report_notification_channel,json=reportNotificationChannel,proto3" json:"report_notification_channel,omitempty"` + ReportPingRole string `protobuf:"bytes,4,opt,name=report_ping_role,json=reportPingRole,proto3" json:"report_ping_role,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ModmailSettings) Reset() { + *x = ModmailSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ModmailSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModmailSettings) ProtoMessage() {} + +func (x *ModmailSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModmailSettings.ProtoReflect.Descriptor instead. +func (*ModmailSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{20} +} + +func (x *ModmailSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *ModmailSettings) GetReportThreadsChannel() string { + if x != nil { + return x.ReportThreadsChannel + } + return "" +} + +func (x *ModmailSettings) GetReportNotificationChannel() string { + if x != nil { + return x.ReportNotificationChannel + } + return "" +} + +func (x *ModmailSettings) GetReportPingRole() string { + if x != nil { + return x.ReportPingRole + } + return "" +} + +// Guild data (channels & roles) +type Channel struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Type int32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"` + Position int32 `protobuf:"varint,4,opt,name=position,proto3" json:"position,omitempty"` + ParentId string `protobuf:"bytes,5,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Channel) Reset() { + *x = Channel{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Channel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Channel) ProtoMessage() {} + +func (x *Channel) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Channel.ProtoReflect.Descriptor instead. +func (*Channel) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{21} +} + +func (x *Channel) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Channel) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Channel) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *Channel) GetPosition() int32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *Channel) GetParentId() string { + if x != nil { + return x.ParentId + } + return "" +} + +type Role struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Color int32 `protobuf:"varint,3,opt,name=color,proto3" json:"color,omitempty"` + Position int32 `protobuf:"varint,4,opt,name=position,proto3" json:"position,omitempty"` + Managed bool `protobuf:"varint,5,opt,name=managed,proto3" json:"managed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Role) Reset() { + *x = Role{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Role) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Role) ProtoMessage() {} + +func (x *Role) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Role.ProtoReflect.Descriptor instead. +func (*Role) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{22} +} + +func (x *Role) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Role) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Role) GetColor() int32 { + if x != nil { + return x.Color + } + return 0 +} + +func (x *Role) GetPosition() int32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *Role) GetManaged() bool { + if x != nil { + return x.Managed + } + return false +} + +type ListChannelsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListChannelsRequest) Reset() { + *x = ListChannelsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListChannelsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListChannelsRequest) ProtoMessage() {} + +func (x *ListChannelsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListChannelsRequest.ProtoReflect.Descriptor instead. +func (*ListChannelsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{23} +} + +func (x *ListChannelsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type ListChannelsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Channels []*Channel `protobuf:"bytes,1,rep,name=channels,proto3" json:"channels,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListChannelsResponse) Reset() { + *x = ListChannelsResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListChannelsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListChannelsResponse) ProtoMessage() {} + +func (x *ListChannelsResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListChannelsResponse.ProtoReflect.Descriptor instead. +func (*ListChannelsResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{24} +} + +func (x *ListChannelsResponse) GetChannels() []*Channel { + if x != nil { + return x.Channels + } + return nil +} + +type ListRolesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListRolesRequest) Reset() { + *x = ListRolesRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListRolesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesRequest) ProtoMessage() {} + +func (x *ListRolesRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesRequest.ProtoReflect.Descriptor instead. +func (*ListRolesRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{25} +} + +func (x *ListRolesRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type ListRolesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Roles []*Role `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListRolesResponse) Reset() { + *x = ListRolesResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListRolesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesResponse) ProtoMessage() {} + +func (x *ListRolesResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesResponse.ProtoReflect.Descriptor instead. +func (*ListRolesResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{26} +} + +func (x *ListRolesResponse) GetRoles() []*Role { + if x != nil { + return x.Roles + } + return nil +} + +// SendComponentsMessage +type SendComponentsMessageRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + ComponentsJson string `protobuf:"bytes,3,opt,name=components_json,json=componentsJson,proto3" json:"components_json,omitempty"` // JSON array of discord LayoutComponents + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendComponentsMessageRequest) Reset() { + *x = SendComponentsMessageRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendComponentsMessageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendComponentsMessageRequest) ProtoMessage() {} + +func (x *SendComponentsMessageRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendComponentsMessageRequest.ProtoReflect.Descriptor instead. +func (*SendComponentsMessageRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{27} +} + +func (x *SendComponentsMessageRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *SendComponentsMessageRequest) GetChannelId() string { + if x != nil { + return x.ChannelId + } + return "" +} + +func (x *SendComponentsMessageRequest) GetComponentsJson() string { + if x != nil { + return x.ComponentsJson + } + return "" +} + +type SendComponentsMessageResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + MessageId string `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendComponentsMessageResponse) Reset() { + *x = SendComponentsMessageResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendComponentsMessageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendComponentsMessageResponse) ProtoMessage() {} + +func (x *SendComponentsMessageResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendComponentsMessageResponse.ProtoReflect.Descriptor instead. +func (*SendComponentsMessageResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{28} +} + +func (x *SendComponentsMessageResponse) GetMessageId() string { + if x != nil { + return x.MessageId + } + return "" +} + +// Template placeholders +type TemplatePlaceholder struct { + state protoimpl.MessageState `protogen:"open.v1"` + Placeholder string `protobuf:"bytes,1,opt,name=placeholder,proto3" json:"placeholder,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TemplatePlaceholder) Reset() { + *x = TemplatePlaceholder{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TemplatePlaceholder) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplatePlaceholder) ProtoMessage() {} + +func (x *TemplatePlaceholder) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TemplatePlaceholder.ProtoReflect.Descriptor instead. +func (*TemplatePlaceholder) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{29} +} + +func (x *TemplatePlaceholder) GetPlaceholder() string { + if x != nil { + return x.Placeholder + } + return "" +} + +func (x *TemplatePlaceholder) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +type GetTemplatePlaceholdersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTemplatePlaceholdersRequest) Reset() { + *x = GetTemplatePlaceholdersRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTemplatePlaceholdersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTemplatePlaceholdersRequest) ProtoMessage() {} + +func (x *GetTemplatePlaceholdersRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTemplatePlaceholdersRequest.ProtoReflect.Descriptor instead. +func (*GetTemplatePlaceholdersRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{30} +} + +type GetTemplatePlaceholdersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Placeholders []*TemplatePlaceholder `protobuf:"bytes,1,rep,name=placeholders,proto3" json:"placeholders,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTemplatePlaceholdersResponse) Reset() { + *x = GetTemplatePlaceholdersResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTemplatePlaceholdersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTemplatePlaceholdersResponse) ProtoMessage() {} + +func (x *GetTemplatePlaceholdersResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTemplatePlaceholdersResponse.ProtoReflect.Descriptor instead. +func (*GetTemplatePlaceholdersResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{31} +} + +func (x *GetTemplatePlaceholdersResponse) GetPlaceholders() []*TemplatePlaceholder { + if x != nil { + return x.Placeholders + } + return nil +} + +var File_heimdallr_v1_guild_settings_proto protoreflect.FileDescriptor + +const file_heimdallr_v1_guild_settings_proto_rawDesc = "" + + "\n" + + "!heimdallr/v1/guild_settings.proto\x12\fheimdallr.v1\"1\n" + + "\x14GetModChannelRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"W\n" + + "\x17UpdateModChannelRequest\x12<\n" + + "\bsettings\x18\x01 \x01(\v2 .heimdallr.v1.ModChannelSettingsR\bsettings\"\\\n" + + "\x12ModChannelSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12+\n" + + "\x11moderator_channel\x18\x02 \x01(\tR\x10moderatorChannel\"9\n" + + "\x1cGetInfractionSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"_\n" + + "\x1fUpdateInfractionSettingsRequest\x12<\n" + + "\bsettings\x18\x01 \x01(\v2 .heimdallr.v1.InfractionSettingsR\bsettings\"\xd6\x01\n" + + "\x12InfractionSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12$\n" + + "\x0ehalf_life_days\x18\x02 \x01(\x01R\fhalfLifeDays\x12:\n" + + "\x1anotify_on_warned_user_join\x18\x03 \x01(\bR\x16notifyOnWarnedUserJoin\x12C\n" + + "\x1enotify_warn_severity_threshold\x18\x04 \x01(\x01R\x1bnotifyWarnSeverityThreshold\"7\n" + + "\x1aGetGatekeepSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"[\n" + + "\x1dUpdateGatekeepSettingsRequest\x12:\n" + + "\bsettings\x18\x01 \x01(\v2\x1e.heimdallr.v1.GatekeepSettingsR\bsettings\"\xdb\x02\n" + + "\x10GatekeepSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x18\n" + + "\aenabled\x18\x02 \x01(\bR\aenabled\x12!\n" + + "\fpending_role\x18\x03 \x01(\tR\vpendingRole\x12#\n" + + "\rapproved_role\x18\x04 \x01(\tR\fapprovedRole\x126\n" + + "\x18add_pending_role_on_join\x18\x05 \x01(\bR\x14addPendingRoleOnJoin\x12)\n" + + "\x10approved_message\x18\x06 \x01(\tR\x0fapprovedMessage\x12.\n" + + "\x13approved_message_v2\x18\a \x01(\bR\x11approvedMessageV2\x127\n" + + "\x18approved_message_v2_json\x18\b \x01(\tR\x15approvedMessageV2Json\"8\n" + + "\x1bGetJoinLeaveSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"]\n" + + "\x1eUpdateJoinLeaveSettingsRequest\x12;\n" + + "\bsettings\x18\x01 \x01(\v2\x1f.heimdallr.v1.JoinLeaveSettingsR\bsettings\"\xac\x03\n" + + "\x11JoinLeaveSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x120\n" + + "\x14join_message_enabled\x18\x02 \x01(\bR\x12joinMessageEnabled\x12!\n" + + "\fjoin_message\x18\x03 \x01(\tR\vjoinMessage\x122\n" + + "\x15leave_message_enabled\x18\x04 \x01(\bR\x13leaveMessageEnabled\x12#\n" + + "\rleave_message\x18\x05 \x01(\tR\fleaveMessage\x12\x18\n" + + "\achannel\x18\x06 \x01(\tR\achannel\x12&\n" + + "\x0fjoin_message_v2\x18\a \x01(\bR\rjoinMessageV2\x12/\n" + + "\x14join_message_v2_json\x18\b \x01(\tR\x11joinMessageV2Json\x12(\n" + + "\x10leave_message_v2\x18\t \x01(\bR\x0eleaveMessageV2\x121\n" + + "\x15leave_message_v2_json\x18\n" + + " \x01(\tR\x12leaveMessageV2Json\"7\n" + + "\x1aGetAntiSpamSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"[\n" + + "\x1dUpdateAntiSpamSettingsRequest\x12:\n" + + "\bsettings\x18\x01 \x01(\v2\x1e.heimdallr.v1.AntiSpamSettingsR\bsettings\"\x88\x01\n" + + "\x10AntiSpamSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x18\n" + + "\aenabled\x18\x02 \x01(\bR\aenabled\x12\x14\n" + + "\x05count\x18\x03 \x01(\x05R\x05count\x12)\n" + + "\x10cooldown_seconds\x18\x04 \x01(\x05R\x0fcooldownSeconds\"8\n" + + "\x1bGetBanFooterSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"]\n" + + "\x1eUpdateBanFooterSettingsRequest\x12;\n" + + "\bsettings\x18\x01 \x01(\v2\x1f.heimdallr.v1.BanFooterSettingsR\bsettings\"g\n" + + "\x11BanFooterSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x16\n" + + "\x06footer\x18\x02 \x01(\tR\x06footer\x12\x1f\n" + + "\valways_send\x18\x03 \x01(\bR\n" + + "alwaysSend\"6\n" + + "\x19GetModmailSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"Y\n" + + "\x1cUpdateModmailSettingsRequest\x129\n" + + "\bsettings\x18\x01 \x01(\v2\x1d.heimdallr.v1.ModmailSettingsR\bsettings\"\xcc\x01\n" + + "\x0fModmailSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x124\n" + + "\x16report_threads_channel\x18\x02 \x01(\tR\x14reportThreadsChannel\x12>\n" + + "\x1breport_notification_channel\x18\x03 \x01(\tR\x19reportNotificationChannel\x12(\n" + + "\x10report_ping_role\x18\x04 \x01(\tR\x0ereportPingRole\"z\n" + + "\aChannel\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x03 \x01(\x05R\x04type\x12\x1a\n" + + "\bposition\x18\x04 \x01(\x05R\bposition\x12\x1b\n" + + "\tparent_id\x18\x05 \x01(\tR\bparentId\"v\n" + + "\x04Role\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + + "\x05color\x18\x03 \x01(\x05R\x05color\x12\x1a\n" + + "\bposition\x18\x04 \x01(\x05R\bposition\x12\x18\n" + + "\amanaged\x18\x05 \x01(\bR\amanaged\"0\n" + + "\x13ListChannelsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"I\n" + + "\x14ListChannelsResponse\x121\n" + + "\bchannels\x18\x01 \x03(\v2\x15.heimdallr.v1.ChannelR\bchannels\"-\n" + + "\x10ListRolesRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"=\n" + + "\x11ListRolesResponse\x12(\n" + + "\x05roles\x18\x01 \x03(\v2\x12.heimdallr.v1.RoleR\x05roles\"\x81\x01\n" + + "\x1cSendComponentsMessageRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x1d\n" + + "\n" + + "channel_id\x18\x02 \x01(\tR\tchannelId\x12'\n" + + "\x0fcomponents_json\x18\x03 \x01(\tR\x0ecomponentsJson\">\n" + + "\x1dSendComponentsMessageResponse\x12\x1d\n" + + "\n" + + "message_id\x18\x01 \x01(\tR\tmessageId\"Y\n" + + "\x13TemplatePlaceholder\x12 \n" + + "\vplaceholder\x18\x01 \x01(\tR\vplaceholder\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\" \n" + + "\x1eGetTemplatePlaceholdersRequest\"h\n" + + "\x1fGetTemplatePlaceholdersResponse\x12E\n" + + "\fplaceholders\x18\x01 \x03(\v2!.heimdallr.v1.TemplatePlaceholderR\fplaceholders2\x9b\x0e\n" + + "\x14GuildSettingsService\x12U\n" + + "\rGetModChannel\x12\".heimdallr.v1.GetModChannelRequest\x1a .heimdallr.v1.ModChannelSettings\x12[\n" + + "\x10UpdateModChannel\x12%.heimdallr.v1.UpdateModChannelRequest\x1a .heimdallr.v1.ModChannelSettings\x12e\n" + + "\x15GetInfractionSettings\x12*.heimdallr.v1.GetInfractionSettingsRequest\x1a .heimdallr.v1.InfractionSettings\x12k\n" + + "\x18UpdateInfractionSettings\x12-.heimdallr.v1.UpdateInfractionSettingsRequest\x1a .heimdallr.v1.InfractionSettings\x12_\n" + + "\x13GetGatekeepSettings\x12(.heimdallr.v1.GetGatekeepSettingsRequest\x1a\x1e.heimdallr.v1.GatekeepSettings\x12e\n" + + "\x16UpdateGatekeepSettings\x12+.heimdallr.v1.UpdateGatekeepSettingsRequest\x1a\x1e.heimdallr.v1.GatekeepSettings\x12b\n" + + "\x14GetJoinLeaveSettings\x12).heimdallr.v1.GetJoinLeaveSettingsRequest\x1a\x1f.heimdallr.v1.JoinLeaveSettings\x12h\n" + + "\x17UpdateJoinLeaveSettings\x12,.heimdallr.v1.UpdateJoinLeaveSettingsRequest\x1a\x1f.heimdallr.v1.JoinLeaveSettings\x12_\n" + + "\x13GetAntiSpamSettings\x12(.heimdallr.v1.GetAntiSpamSettingsRequest\x1a\x1e.heimdallr.v1.AntiSpamSettings\x12e\n" + + "\x16UpdateAntiSpamSettings\x12+.heimdallr.v1.UpdateAntiSpamSettingsRequest\x1a\x1e.heimdallr.v1.AntiSpamSettings\x12b\n" + + "\x14GetBanFooterSettings\x12).heimdallr.v1.GetBanFooterSettingsRequest\x1a\x1f.heimdallr.v1.BanFooterSettings\x12h\n" + + "\x17UpdateBanFooterSettings\x12,.heimdallr.v1.UpdateBanFooterSettingsRequest\x1a\x1f.heimdallr.v1.BanFooterSettings\x12\\\n" + + "\x12GetModmailSettings\x12'.heimdallr.v1.GetModmailSettingsRequest\x1a\x1d.heimdallr.v1.ModmailSettings\x12b\n" + + "\x15UpdateModmailSettings\x12*.heimdallr.v1.UpdateModmailSettingsRequest\x1a\x1d.heimdallr.v1.ModmailSettings\x12U\n" + + "\fListChannels\x12!.heimdallr.v1.ListChannelsRequest\x1a\".heimdallr.v1.ListChannelsResponse\x12L\n" + + "\tListRoles\x12\x1e.heimdallr.v1.ListRolesRequest\x1a\x1f.heimdallr.v1.ListRolesResponse\x12v\n" + + "\x17GetTemplatePlaceholders\x12,.heimdallr.v1.GetTemplatePlaceholdersRequest\x1a-.heimdallr.v1.GetTemplatePlaceholdersResponse\x12p\n" + + "\x15SendComponentsMessage\x12*.heimdallr.v1.SendComponentsMessageRequest\x1a+.heimdallr.v1.SendComponentsMessageResponseB\xb7\x01\n" + + "\x10com.heimdallr.v1B\x12GuildSettingsProtoP\x01Z>github.com/NLLCommunity/heimdallr/gen/heimdallr/v1;heimdallrv1\xa2\x02\x03HXX\xaa\x02\fHeimdallr.V1\xca\x02\fHeimdallr\\V1\xe2\x02\x18Heimdallr\\V1\\GPBMetadata\xea\x02\rHeimdallr::V1b\x06proto3" + +var ( + file_heimdallr_v1_guild_settings_proto_rawDescOnce sync.Once + file_heimdallr_v1_guild_settings_proto_rawDescData []byte +) + +func file_heimdallr_v1_guild_settings_proto_rawDescGZIP() []byte { + file_heimdallr_v1_guild_settings_proto_rawDescOnce.Do(func() { + file_heimdallr_v1_guild_settings_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_heimdallr_v1_guild_settings_proto_rawDesc), len(file_heimdallr_v1_guild_settings_proto_rawDesc))) + }) + return file_heimdallr_v1_guild_settings_proto_rawDescData +} + +var file_heimdallr_v1_guild_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_heimdallr_v1_guild_settings_proto_goTypes = []any{ + (*GetModChannelRequest)(nil), // 0: heimdallr.v1.GetModChannelRequest + (*UpdateModChannelRequest)(nil), // 1: heimdallr.v1.UpdateModChannelRequest + (*ModChannelSettings)(nil), // 2: heimdallr.v1.ModChannelSettings + (*GetInfractionSettingsRequest)(nil), // 3: heimdallr.v1.GetInfractionSettingsRequest + (*UpdateInfractionSettingsRequest)(nil), // 4: heimdallr.v1.UpdateInfractionSettingsRequest + (*InfractionSettings)(nil), // 5: heimdallr.v1.InfractionSettings + (*GetGatekeepSettingsRequest)(nil), // 6: heimdallr.v1.GetGatekeepSettingsRequest + (*UpdateGatekeepSettingsRequest)(nil), // 7: heimdallr.v1.UpdateGatekeepSettingsRequest + (*GatekeepSettings)(nil), // 8: heimdallr.v1.GatekeepSettings + (*GetJoinLeaveSettingsRequest)(nil), // 9: heimdallr.v1.GetJoinLeaveSettingsRequest + (*UpdateJoinLeaveSettingsRequest)(nil), // 10: heimdallr.v1.UpdateJoinLeaveSettingsRequest + (*JoinLeaveSettings)(nil), // 11: heimdallr.v1.JoinLeaveSettings + (*GetAntiSpamSettingsRequest)(nil), // 12: heimdallr.v1.GetAntiSpamSettingsRequest + (*UpdateAntiSpamSettingsRequest)(nil), // 13: heimdallr.v1.UpdateAntiSpamSettingsRequest + (*AntiSpamSettings)(nil), // 14: heimdallr.v1.AntiSpamSettings + (*GetBanFooterSettingsRequest)(nil), // 15: heimdallr.v1.GetBanFooterSettingsRequest + (*UpdateBanFooterSettingsRequest)(nil), // 16: heimdallr.v1.UpdateBanFooterSettingsRequest + (*BanFooterSettings)(nil), // 17: heimdallr.v1.BanFooterSettings + (*GetModmailSettingsRequest)(nil), // 18: heimdallr.v1.GetModmailSettingsRequest + (*UpdateModmailSettingsRequest)(nil), // 19: heimdallr.v1.UpdateModmailSettingsRequest + (*ModmailSettings)(nil), // 20: heimdallr.v1.ModmailSettings + (*Channel)(nil), // 21: heimdallr.v1.Channel + (*Role)(nil), // 22: heimdallr.v1.Role + (*ListChannelsRequest)(nil), // 23: heimdallr.v1.ListChannelsRequest + (*ListChannelsResponse)(nil), // 24: heimdallr.v1.ListChannelsResponse + (*ListRolesRequest)(nil), // 25: heimdallr.v1.ListRolesRequest + (*ListRolesResponse)(nil), // 26: heimdallr.v1.ListRolesResponse + (*SendComponentsMessageRequest)(nil), // 27: heimdallr.v1.SendComponentsMessageRequest + (*SendComponentsMessageResponse)(nil), // 28: heimdallr.v1.SendComponentsMessageResponse + (*TemplatePlaceholder)(nil), // 29: heimdallr.v1.TemplatePlaceholder + (*GetTemplatePlaceholdersRequest)(nil), // 30: heimdallr.v1.GetTemplatePlaceholdersRequest + (*GetTemplatePlaceholdersResponse)(nil), // 31: heimdallr.v1.GetTemplatePlaceholdersResponse +} +var file_heimdallr_v1_guild_settings_proto_depIdxs = []int32{ + 2, // 0: heimdallr.v1.UpdateModChannelRequest.settings:type_name -> heimdallr.v1.ModChannelSettings + 5, // 1: heimdallr.v1.UpdateInfractionSettingsRequest.settings:type_name -> heimdallr.v1.InfractionSettings + 8, // 2: heimdallr.v1.UpdateGatekeepSettingsRequest.settings:type_name -> heimdallr.v1.GatekeepSettings + 11, // 3: heimdallr.v1.UpdateJoinLeaveSettingsRequest.settings:type_name -> heimdallr.v1.JoinLeaveSettings + 14, // 4: heimdallr.v1.UpdateAntiSpamSettingsRequest.settings:type_name -> heimdallr.v1.AntiSpamSettings + 17, // 5: heimdallr.v1.UpdateBanFooterSettingsRequest.settings:type_name -> heimdallr.v1.BanFooterSettings + 20, // 6: heimdallr.v1.UpdateModmailSettingsRequest.settings:type_name -> heimdallr.v1.ModmailSettings + 21, // 7: heimdallr.v1.ListChannelsResponse.channels:type_name -> heimdallr.v1.Channel + 22, // 8: heimdallr.v1.ListRolesResponse.roles:type_name -> heimdallr.v1.Role + 29, // 9: heimdallr.v1.GetTemplatePlaceholdersResponse.placeholders:type_name -> heimdallr.v1.TemplatePlaceholder + 0, // 10: heimdallr.v1.GuildSettingsService.GetModChannel:input_type -> heimdallr.v1.GetModChannelRequest + 1, // 11: heimdallr.v1.GuildSettingsService.UpdateModChannel:input_type -> heimdallr.v1.UpdateModChannelRequest + 3, // 12: heimdallr.v1.GuildSettingsService.GetInfractionSettings:input_type -> heimdallr.v1.GetInfractionSettingsRequest + 4, // 13: heimdallr.v1.GuildSettingsService.UpdateInfractionSettings:input_type -> heimdallr.v1.UpdateInfractionSettingsRequest + 6, // 14: heimdallr.v1.GuildSettingsService.GetGatekeepSettings:input_type -> heimdallr.v1.GetGatekeepSettingsRequest + 7, // 15: heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings:input_type -> heimdallr.v1.UpdateGatekeepSettingsRequest + 9, // 16: heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings:input_type -> heimdallr.v1.GetJoinLeaveSettingsRequest + 10, // 17: heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings:input_type -> heimdallr.v1.UpdateJoinLeaveSettingsRequest + 12, // 18: heimdallr.v1.GuildSettingsService.GetAntiSpamSettings:input_type -> heimdallr.v1.GetAntiSpamSettingsRequest + 13, // 19: heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings:input_type -> heimdallr.v1.UpdateAntiSpamSettingsRequest + 15, // 20: heimdallr.v1.GuildSettingsService.GetBanFooterSettings:input_type -> heimdallr.v1.GetBanFooterSettingsRequest + 16, // 21: heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings:input_type -> heimdallr.v1.UpdateBanFooterSettingsRequest + 18, // 22: heimdallr.v1.GuildSettingsService.GetModmailSettings:input_type -> heimdallr.v1.GetModmailSettingsRequest + 19, // 23: heimdallr.v1.GuildSettingsService.UpdateModmailSettings:input_type -> heimdallr.v1.UpdateModmailSettingsRequest + 23, // 24: heimdallr.v1.GuildSettingsService.ListChannels:input_type -> heimdallr.v1.ListChannelsRequest + 25, // 25: heimdallr.v1.GuildSettingsService.ListRoles:input_type -> heimdallr.v1.ListRolesRequest + 30, // 26: heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders:input_type -> heimdallr.v1.GetTemplatePlaceholdersRequest + 27, // 27: heimdallr.v1.GuildSettingsService.SendComponentsMessage:input_type -> heimdallr.v1.SendComponentsMessageRequest + 2, // 28: heimdallr.v1.GuildSettingsService.GetModChannel:output_type -> heimdallr.v1.ModChannelSettings + 2, // 29: heimdallr.v1.GuildSettingsService.UpdateModChannel:output_type -> heimdallr.v1.ModChannelSettings + 5, // 30: heimdallr.v1.GuildSettingsService.GetInfractionSettings:output_type -> heimdallr.v1.InfractionSettings + 5, // 31: heimdallr.v1.GuildSettingsService.UpdateInfractionSettings:output_type -> heimdallr.v1.InfractionSettings + 8, // 32: heimdallr.v1.GuildSettingsService.GetGatekeepSettings:output_type -> heimdallr.v1.GatekeepSettings + 8, // 33: heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings:output_type -> heimdallr.v1.GatekeepSettings + 11, // 34: heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings:output_type -> heimdallr.v1.JoinLeaveSettings + 11, // 35: heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings:output_type -> heimdallr.v1.JoinLeaveSettings + 14, // 36: heimdallr.v1.GuildSettingsService.GetAntiSpamSettings:output_type -> heimdallr.v1.AntiSpamSettings + 14, // 37: heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings:output_type -> heimdallr.v1.AntiSpamSettings + 17, // 38: heimdallr.v1.GuildSettingsService.GetBanFooterSettings:output_type -> heimdallr.v1.BanFooterSettings + 17, // 39: heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings:output_type -> heimdallr.v1.BanFooterSettings + 20, // 40: heimdallr.v1.GuildSettingsService.GetModmailSettings:output_type -> heimdallr.v1.ModmailSettings + 20, // 41: heimdallr.v1.GuildSettingsService.UpdateModmailSettings:output_type -> heimdallr.v1.ModmailSettings + 24, // 42: heimdallr.v1.GuildSettingsService.ListChannels:output_type -> heimdallr.v1.ListChannelsResponse + 26, // 43: heimdallr.v1.GuildSettingsService.ListRoles:output_type -> heimdallr.v1.ListRolesResponse + 31, // 44: heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders:output_type -> heimdallr.v1.GetTemplatePlaceholdersResponse + 28, // 45: heimdallr.v1.GuildSettingsService.SendComponentsMessage:output_type -> heimdallr.v1.SendComponentsMessageResponse + 28, // [28:46] is the sub-list for method output_type + 10, // [10:28] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_heimdallr_v1_guild_settings_proto_init() } +func file_heimdallr_v1_guild_settings_proto_init() { + if File_heimdallr_v1_guild_settings_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_heimdallr_v1_guild_settings_proto_rawDesc), len(file_heimdallr_v1_guild_settings_proto_rawDesc)), + NumEnums: 0, + NumMessages: 32, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_heimdallr_v1_guild_settings_proto_goTypes, + DependencyIndexes: file_heimdallr_v1_guild_settings_proto_depIdxs, + MessageInfos: file_heimdallr_v1_guild_settings_proto_msgTypes, + }.Build() + File_heimdallr_v1_guild_settings_proto = out.File + file_heimdallr_v1_guild_settings_proto_goTypes = nil + file_heimdallr_v1_guild_settings_proto_depIdxs = nil +} diff --git a/heimdallr/gen/heimdallr/v1/heimdallrv1connect/auth.connect.go b/heimdallr/gen/heimdallr/v1/heimdallrv1connect/auth.connect.go new file mode 100644 index 0000000..abdb556 --- /dev/null +++ b/heimdallr/gen/heimdallr/v1/heimdallrv1connect/auth.connect.go @@ -0,0 +1,242 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: heimdallr/v1/auth.proto + +package heimdallrv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AuthServiceName is the fully-qualified name of the AuthService service. + AuthServiceName = "heimdallr.v1.AuthService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AuthServiceGetLoginURLProcedure is the fully-qualified name of the AuthService's GetLoginURL RPC. + AuthServiceGetLoginURLProcedure = "/heimdallr.v1.AuthService/GetLoginURL" + // AuthServiceExchangeCodeProcedure is the fully-qualified name of the AuthService's ExchangeCode + // RPC. + AuthServiceExchangeCodeProcedure = "/heimdallr.v1.AuthService/ExchangeCode" + // AuthServiceGetCurrentUserProcedure is the fully-qualified name of the AuthService's + // GetCurrentUser RPC. + AuthServiceGetCurrentUserProcedure = "/heimdallr.v1.AuthService/GetCurrentUser" + // AuthServiceListGuildsProcedure is the fully-qualified name of the AuthService's ListGuilds RPC. + AuthServiceListGuildsProcedure = "/heimdallr.v1.AuthService/ListGuilds" + // AuthServiceLogoutProcedure is the fully-qualified name of the AuthService's Logout RPC. + AuthServiceLogoutProcedure = "/heimdallr.v1.AuthService/Logout" +) + +// AuthServiceClient is a client for the heimdallr.v1.AuthService service. +type AuthServiceClient interface { + GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) + ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) + GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) + ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) + Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) +} + +// NewAuthServiceClient constructs a client for the heimdallr.v1.AuthService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAuthServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AuthServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + authServiceMethods := v1.File_heimdallr_v1_auth_proto.Services().ByName("AuthService").Methods() + return &authServiceClient{ + getLoginURL: connect.NewClient[v1.GetLoginURLRequest, v1.GetLoginURLResponse]( + httpClient, + baseURL+AuthServiceGetLoginURLProcedure, + connect.WithSchema(authServiceMethods.ByName("GetLoginURL")), + connect.WithClientOptions(opts...), + ), + exchangeCode: connect.NewClient[v1.ExchangeCodeRequest, v1.ExchangeCodeResponse]( + httpClient, + baseURL+AuthServiceExchangeCodeProcedure, + connect.WithSchema(authServiceMethods.ByName("ExchangeCode")), + connect.WithClientOptions(opts...), + ), + getCurrentUser: connect.NewClient[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse]( + httpClient, + baseURL+AuthServiceGetCurrentUserProcedure, + connect.WithSchema(authServiceMethods.ByName("GetCurrentUser")), + connect.WithClientOptions(opts...), + ), + listGuilds: connect.NewClient[v1.ListGuildsRequest, v1.ListGuildsResponse]( + httpClient, + baseURL+AuthServiceListGuildsProcedure, + connect.WithSchema(authServiceMethods.ByName("ListGuilds")), + connect.WithClientOptions(opts...), + ), + logout: connect.NewClient[v1.LogoutRequest, v1.LogoutResponse]( + httpClient, + baseURL+AuthServiceLogoutProcedure, + connect.WithSchema(authServiceMethods.ByName("Logout")), + connect.WithClientOptions(opts...), + ), + } +} + +// authServiceClient implements AuthServiceClient. +type authServiceClient struct { + getLoginURL *connect.Client[v1.GetLoginURLRequest, v1.GetLoginURLResponse] + exchangeCode *connect.Client[v1.ExchangeCodeRequest, v1.ExchangeCodeResponse] + getCurrentUser *connect.Client[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse] + listGuilds *connect.Client[v1.ListGuildsRequest, v1.ListGuildsResponse] + logout *connect.Client[v1.LogoutRequest, v1.LogoutResponse] +} + +// GetLoginURL calls heimdallr.v1.AuthService.GetLoginURL. +func (c *authServiceClient) GetLoginURL(ctx context.Context, req *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) { + response, err := c.getLoginURL.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ExchangeCode calls heimdallr.v1.AuthService.ExchangeCode. +func (c *authServiceClient) ExchangeCode(ctx context.Context, req *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) { + response, err := c.exchangeCode.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetCurrentUser calls heimdallr.v1.AuthService.GetCurrentUser. +func (c *authServiceClient) GetCurrentUser(ctx context.Context, req *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) { + response, err := c.getCurrentUser.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListGuilds calls heimdallr.v1.AuthService.ListGuilds. +func (c *authServiceClient) ListGuilds(ctx context.Context, req *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) { + response, err := c.listGuilds.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// Logout calls heimdallr.v1.AuthService.Logout. +func (c *authServiceClient) Logout(ctx context.Context, req *v1.LogoutRequest) (*v1.LogoutResponse, error) { + response, err := c.logout.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// AuthServiceHandler is an implementation of the heimdallr.v1.AuthService service. +type AuthServiceHandler interface { + GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) + ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) + GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) + ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) + Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) +} + +// NewAuthServiceHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAuthServiceHandler(svc AuthServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + authServiceMethods := v1.File_heimdallr_v1_auth_proto.Services().ByName("AuthService").Methods() + authServiceGetLoginURLHandler := connect.NewUnaryHandlerSimple( + AuthServiceGetLoginURLProcedure, + svc.GetLoginURL, + connect.WithSchema(authServiceMethods.ByName("GetLoginURL")), + connect.WithHandlerOptions(opts...), + ) + authServiceExchangeCodeHandler := connect.NewUnaryHandlerSimple( + AuthServiceExchangeCodeProcedure, + svc.ExchangeCode, + connect.WithSchema(authServiceMethods.ByName("ExchangeCode")), + connect.WithHandlerOptions(opts...), + ) + authServiceGetCurrentUserHandler := connect.NewUnaryHandlerSimple( + AuthServiceGetCurrentUserProcedure, + svc.GetCurrentUser, + connect.WithSchema(authServiceMethods.ByName("GetCurrentUser")), + connect.WithHandlerOptions(opts...), + ) + authServiceListGuildsHandler := connect.NewUnaryHandlerSimple( + AuthServiceListGuildsProcedure, + svc.ListGuilds, + connect.WithSchema(authServiceMethods.ByName("ListGuilds")), + connect.WithHandlerOptions(opts...), + ) + authServiceLogoutHandler := connect.NewUnaryHandlerSimple( + AuthServiceLogoutProcedure, + svc.Logout, + connect.WithSchema(authServiceMethods.ByName("Logout")), + connect.WithHandlerOptions(opts...), + ) + return "/heimdallr.v1.AuthService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AuthServiceGetLoginURLProcedure: + authServiceGetLoginURLHandler.ServeHTTP(w, r) + case AuthServiceExchangeCodeProcedure: + authServiceExchangeCodeHandler.ServeHTTP(w, r) + case AuthServiceGetCurrentUserProcedure: + authServiceGetCurrentUserHandler.ServeHTTP(w, r) + case AuthServiceListGuildsProcedure: + authServiceListGuildsHandler.ServeHTTP(w, r) + case AuthServiceLogoutProcedure: + authServiceLogoutHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAuthServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAuthServiceHandler struct{} + +func (UnimplementedAuthServiceHandler) GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.GetLoginURL is not implemented")) +} + +func (UnimplementedAuthServiceHandler) ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.ExchangeCode is not implemented")) +} + +func (UnimplementedAuthServiceHandler) GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.GetCurrentUser is not implemented")) +} + +func (UnimplementedAuthServiceHandler) ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.ListGuilds is not implemented")) +} + +func (UnimplementedAuthServiceHandler) Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.Logout is not implemented")) +} diff --git a/heimdallr/gen/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go b/heimdallr/gen/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go new file mode 100644 index 0000000..e435a8b --- /dev/null +++ b/heimdallr/gen/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go @@ -0,0 +1,675 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: heimdallr/v1/guild_settings.proto + +package heimdallrv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // GuildSettingsServiceName is the fully-qualified name of the GuildSettingsService service. + GuildSettingsServiceName = "heimdallr.v1.GuildSettingsService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GuildSettingsServiceGetModChannelProcedure is the fully-qualified name of the + // GuildSettingsService's GetModChannel RPC. + GuildSettingsServiceGetModChannelProcedure = "/heimdallr.v1.GuildSettingsService/GetModChannel" + // GuildSettingsServiceUpdateModChannelProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateModChannel RPC. + GuildSettingsServiceUpdateModChannelProcedure = "/heimdallr.v1.GuildSettingsService/UpdateModChannel" + // GuildSettingsServiceGetInfractionSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetInfractionSettings RPC. + GuildSettingsServiceGetInfractionSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetInfractionSettings" + // GuildSettingsServiceUpdateInfractionSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateInfractionSettings RPC. + GuildSettingsServiceUpdateInfractionSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateInfractionSettings" + // GuildSettingsServiceGetGatekeepSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetGatekeepSettings RPC. + GuildSettingsServiceGetGatekeepSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetGatekeepSettings" + // GuildSettingsServiceUpdateGatekeepSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateGatekeepSettings RPC. + GuildSettingsServiceUpdateGatekeepSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateGatekeepSettings" + // GuildSettingsServiceGetJoinLeaveSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetJoinLeaveSettings RPC. + GuildSettingsServiceGetJoinLeaveSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetJoinLeaveSettings" + // GuildSettingsServiceUpdateJoinLeaveSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateJoinLeaveSettings RPC. + GuildSettingsServiceUpdateJoinLeaveSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateJoinLeaveSettings" + // GuildSettingsServiceGetAntiSpamSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetAntiSpamSettings RPC. + GuildSettingsServiceGetAntiSpamSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetAntiSpamSettings" + // GuildSettingsServiceUpdateAntiSpamSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateAntiSpamSettings RPC. + GuildSettingsServiceUpdateAntiSpamSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateAntiSpamSettings" + // GuildSettingsServiceGetBanFooterSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetBanFooterSettings RPC. + GuildSettingsServiceGetBanFooterSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetBanFooterSettings" + // GuildSettingsServiceUpdateBanFooterSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateBanFooterSettings RPC. + GuildSettingsServiceUpdateBanFooterSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateBanFooterSettings" + // GuildSettingsServiceGetModmailSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetModmailSettings RPC. + GuildSettingsServiceGetModmailSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetModmailSettings" + // GuildSettingsServiceUpdateModmailSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateModmailSettings RPC. + GuildSettingsServiceUpdateModmailSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateModmailSettings" + // GuildSettingsServiceListChannelsProcedure is the fully-qualified name of the + // GuildSettingsService's ListChannels RPC. + GuildSettingsServiceListChannelsProcedure = "/heimdallr.v1.GuildSettingsService/ListChannels" + // GuildSettingsServiceListRolesProcedure is the fully-qualified name of the GuildSettingsService's + // ListRoles RPC. + GuildSettingsServiceListRolesProcedure = "/heimdallr.v1.GuildSettingsService/ListRoles" + // GuildSettingsServiceGetTemplatePlaceholdersProcedure is the fully-qualified name of the + // GuildSettingsService's GetTemplatePlaceholders RPC. + GuildSettingsServiceGetTemplatePlaceholdersProcedure = "/heimdallr.v1.GuildSettingsService/GetTemplatePlaceholders" + // GuildSettingsServiceSendComponentsMessageProcedure is the fully-qualified name of the + // GuildSettingsService's SendComponentsMessage RPC. + GuildSettingsServiceSendComponentsMessageProcedure = "/heimdallr.v1.GuildSettingsService/SendComponentsMessage" +) + +// GuildSettingsServiceClient is a client for the heimdallr.v1.GuildSettingsService service. +type GuildSettingsServiceClient interface { + GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) + UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) + GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) + UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) + GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) + UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) + ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) + ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) + GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) + SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) +} + +// NewGuildSettingsServiceClient constructs a client for the heimdallr.v1.GuildSettingsService +// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for +// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply +// the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewGuildSettingsServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GuildSettingsServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + guildSettingsServiceMethods := v1.File_heimdallr_v1_guild_settings_proto.Services().ByName("GuildSettingsService").Methods() + return &guildSettingsServiceClient{ + getModChannel: connect.NewClient[v1.GetModChannelRequest, v1.ModChannelSettings]( + httpClient, + baseURL+GuildSettingsServiceGetModChannelProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModChannel")), + connect.WithClientOptions(opts...), + ), + updateModChannel: connect.NewClient[v1.UpdateModChannelRequest, v1.ModChannelSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateModChannelProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModChannel")), + connect.WithClientOptions(opts...), + ), + getInfractionSettings: connect.NewClient[v1.GetInfractionSettingsRequest, v1.InfractionSettings]( + httpClient, + baseURL+GuildSettingsServiceGetInfractionSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetInfractionSettings")), + connect.WithClientOptions(opts...), + ), + updateInfractionSettings: connect.NewClient[v1.UpdateInfractionSettingsRequest, v1.InfractionSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateInfractionSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateInfractionSettings")), + connect.WithClientOptions(opts...), + ), + getGatekeepSettings: connect.NewClient[v1.GetGatekeepSettingsRequest, v1.GatekeepSettings]( + httpClient, + baseURL+GuildSettingsServiceGetGatekeepSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetGatekeepSettings")), + connect.WithClientOptions(opts...), + ), + updateGatekeepSettings: connect.NewClient[v1.UpdateGatekeepSettingsRequest, v1.GatekeepSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateGatekeepSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateGatekeepSettings")), + connect.WithClientOptions(opts...), + ), + getJoinLeaveSettings: connect.NewClient[v1.GetJoinLeaveSettingsRequest, v1.JoinLeaveSettings]( + httpClient, + baseURL+GuildSettingsServiceGetJoinLeaveSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetJoinLeaveSettings")), + connect.WithClientOptions(opts...), + ), + updateJoinLeaveSettings: connect.NewClient[v1.UpdateJoinLeaveSettingsRequest, v1.JoinLeaveSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateJoinLeaveSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateJoinLeaveSettings")), + connect.WithClientOptions(opts...), + ), + getAntiSpamSettings: connect.NewClient[v1.GetAntiSpamSettingsRequest, v1.AntiSpamSettings]( + httpClient, + baseURL+GuildSettingsServiceGetAntiSpamSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetAntiSpamSettings")), + connect.WithClientOptions(opts...), + ), + updateAntiSpamSettings: connect.NewClient[v1.UpdateAntiSpamSettingsRequest, v1.AntiSpamSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateAntiSpamSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateAntiSpamSettings")), + connect.WithClientOptions(opts...), + ), + getBanFooterSettings: connect.NewClient[v1.GetBanFooterSettingsRequest, v1.BanFooterSettings]( + httpClient, + baseURL+GuildSettingsServiceGetBanFooterSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetBanFooterSettings")), + connect.WithClientOptions(opts...), + ), + updateBanFooterSettings: connect.NewClient[v1.UpdateBanFooterSettingsRequest, v1.BanFooterSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateBanFooterSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateBanFooterSettings")), + connect.WithClientOptions(opts...), + ), + getModmailSettings: connect.NewClient[v1.GetModmailSettingsRequest, v1.ModmailSettings]( + httpClient, + baseURL+GuildSettingsServiceGetModmailSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModmailSettings")), + connect.WithClientOptions(opts...), + ), + updateModmailSettings: connect.NewClient[v1.UpdateModmailSettingsRequest, v1.ModmailSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateModmailSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModmailSettings")), + connect.WithClientOptions(opts...), + ), + listChannels: connect.NewClient[v1.ListChannelsRequest, v1.ListChannelsResponse]( + httpClient, + baseURL+GuildSettingsServiceListChannelsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListChannels")), + connect.WithClientOptions(opts...), + ), + listRoles: connect.NewClient[v1.ListRolesRequest, v1.ListRolesResponse]( + httpClient, + baseURL+GuildSettingsServiceListRolesProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListRoles")), + connect.WithClientOptions(opts...), + ), + getTemplatePlaceholders: connect.NewClient[v1.GetTemplatePlaceholdersRequest, v1.GetTemplatePlaceholdersResponse]( + httpClient, + baseURL+GuildSettingsServiceGetTemplatePlaceholdersProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetTemplatePlaceholders")), + connect.WithClientOptions(opts...), + ), + sendComponentsMessage: connect.NewClient[v1.SendComponentsMessageRequest, v1.SendComponentsMessageResponse]( + httpClient, + baseURL+GuildSettingsServiceSendComponentsMessageProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("SendComponentsMessage")), + connect.WithClientOptions(opts...), + ), + } +} + +// guildSettingsServiceClient implements GuildSettingsServiceClient. +type guildSettingsServiceClient struct { + getModChannel *connect.Client[v1.GetModChannelRequest, v1.ModChannelSettings] + updateModChannel *connect.Client[v1.UpdateModChannelRequest, v1.ModChannelSettings] + getInfractionSettings *connect.Client[v1.GetInfractionSettingsRequest, v1.InfractionSettings] + updateInfractionSettings *connect.Client[v1.UpdateInfractionSettingsRequest, v1.InfractionSettings] + getGatekeepSettings *connect.Client[v1.GetGatekeepSettingsRequest, v1.GatekeepSettings] + updateGatekeepSettings *connect.Client[v1.UpdateGatekeepSettingsRequest, v1.GatekeepSettings] + getJoinLeaveSettings *connect.Client[v1.GetJoinLeaveSettingsRequest, v1.JoinLeaveSettings] + updateJoinLeaveSettings *connect.Client[v1.UpdateJoinLeaveSettingsRequest, v1.JoinLeaveSettings] + getAntiSpamSettings *connect.Client[v1.GetAntiSpamSettingsRequest, v1.AntiSpamSettings] + updateAntiSpamSettings *connect.Client[v1.UpdateAntiSpamSettingsRequest, v1.AntiSpamSettings] + getBanFooterSettings *connect.Client[v1.GetBanFooterSettingsRequest, v1.BanFooterSettings] + updateBanFooterSettings *connect.Client[v1.UpdateBanFooterSettingsRequest, v1.BanFooterSettings] + getModmailSettings *connect.Client[v1.GetModmailSettingsRequest, v1.ModmailSettings] + updateModmailSettings *connect.Client[v1.UpdateModmailSettingsRequest, v1.ModmailSettings] + listChannels *connect.Client[v1.ListChannelsRequest, v1.ListChannelsResponse] + listRoles *connect.Client[v1.ListRolesRequest, v1.ListRolesResponse] + getTemplatePlaceholders *connect.Client[v1.GetTemplatePlaceholdersRequest, v1.GetTemplatePlaceholdersResponse] + sendComponentsMessage *connect.Client[v1.SendComponentsMessageRequest, v1.SendComponentsMessageResponse] +} + +// GetModChannel calls heimdallr.v1.GuildSettingsService.GetModChannel. +func (c *guildSettingsServiceClient) GetModChannel(ctx context.Context, req *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) { + response, err := c.getModChannel.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateModChannel calls heimdallr.v1.GuildSettingsService.UpdateModChannel. +func (c *guildSettingsServiceClient) UpdateModChannel(ctx context.Context, req *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) { + response, err := c.updateModChannel.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetInfractionSettings calls heimdallr.v1.GuildSettingsService.GetInfractionSettings. +func (c *guildSettingsServiceClient) GetInfractionSettings(ctx context.Context, req *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) { + response, err := c.getInfractionSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateInfractionSettings calls heimdallr.v1.GuildSettingsService.UpdateInfractionSettings. +func (c *guildSettingsServiceClient) UpdateInfractionSettings(ctx context.Context, req *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) { + response, err := c.updateInfractionSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetGatekeepSettings calls heimdallr.v1.GuildSettingsService.GetGatekeepSettings. +func (c *guildSettingsServiceClient) GetGatekeepSettings(ctx context.Context, req *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + response, err := c.getGatekeepSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateGatekeepSettings calls heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings. +func (c *guildSettingsServiceClient) UpdateGatekeepSettings(ctx context.Context, req *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + response, err := c.updateGatekeepSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetJoinLeaveSettings calls heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings. +func (c *guildSettingsServiceClient) GetJoinLeaveSettings(ctx context.Context, req *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + response, err := c.getJoinLeaveSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateJoinLeaveSettings calls heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings. +func (c *guildSettingsServiceClient) UpdateJoinLeaveSettings(ctx context.Context, req *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + response, err := c.updateJoinLeaveSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetAntiSpamSettings calls heimdallr.v1.GuildSettingsService.GetAntiSpamSettings. +func (c *guildSettingsServiceClient) GetAntiSpamSettings(ctx context.Context, req *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + response, err := c.getAntiSpamSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateAntiSpamSettings calls heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings. +func (c *guildSettingsServiceClient) UpdateAntiSpamSettings(ctx context.Context, req *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + response, err := c.updateAntiSpamSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetBanFooterSettings calls heimdallr.v1.GuildSettingsService.GetBanFooterSettings. +func (c *guildSettingsServiceClient) GetBanFooterSettings(ctx context.Context, req *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + response, err := c.getBanFooterSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateBanFooterSettings calls heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings. +func (c *guildSettingsServiceClient) UpdateBanFooterSettings(ctx context.Context, req *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + response, err := c.updateBanFooterSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetModmailSettings calls heimdallr.v1.GuildSettingsService.GetModmailSettings. +func (c *guildSettingsServiceClient) GetModmailSettings(ctx context.Context, req *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) { + response, err := c.getModmailSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateModmailSettings calls heimdallr.v1.GuildSettingsService.UpdateModmailSettings. +func (c *guildSettingsServiceClient) UpdateModmailSettings(ctx context.Context, req *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) { + response, err := c.updateModmailSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListChannels calls heimdallr.v1.GuildSettingsService.ListChannels. +func (c *guildSettingsServiceClient) ListChannels(ctx context.Context, req *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) { + response, err := c.listChannels.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListRoles calls heimdallr.v1.GuildSettingsService.ListRoles. +func (c *guildSettingsServiceClient) ListRoles(ctx context.Context, req *v1.ListRolesRequest) (*v1.ListRolesResponse, error) { + response, err := c.listRoles.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetTemplatePlaceholders calls heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders. +func (c *guildSettingsServiceClient) GetTemplatePlaceholders(ctx context.Context, req *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) { + response, err := c.getTemplatePlaceholders.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// SendComponentsMessage calls heimdallr.v1.GuildSettingsService.SendComponentsMessage. +func (c *guildSettingsServiceClient) SendComponentsMessage(ctx context.Context, req *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) { + response, err := c.sendComponentsMessage.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GuildSettingsServiceHandler is an implementation of the heimdallr.v1.GuildSettingsService +// service. +type GuildSettingsServiceHandler interface { + GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) + UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) + GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) + UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) + GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) + UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) + ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) + ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) + GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) + SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) +} + +// NewGuildSettingsServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewGuildSettingsServiceHandler(svc GuildSettingsServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + guildSettingsServiceMethods := v1.File_heimdallr_v1_guild_settings_proto.Services().ByName("GuildSettingsService").Methods() + guildSettingsServiceGetModChannelHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetModChannelProcedure, + svc.GetModChannel, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModChannel")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateModChannelHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateModChannelProcedure, + svc.UpdateModChannel, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModChannel")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetInfractionSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetInfractionSettingsProcedure, + svc.GetInfractionSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetInfractionSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateInfractionSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateInfractionSettingsProcedure, + svc.UpdateInfractionSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateInfractionSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetGatekeepSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetGatekeepSettingsProcedure, + svc.GetGatekeepSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetGatekeepSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateGatekeepSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateGatekeepSettingsProcedure, + svc.UpdateGatekeepSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateGatekeepSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetJoinLeaveSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetJoinLeaveSettingsProcedure, + svc.GetJoinLeaveSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetJoinLeaveSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateJoinLeaveSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateJoinLeaveSettingsProcedure, + svc.UpdateJoinLeaveSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateJoinLeaveSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetAntiSpamSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetAntiSpamSettingsProcedure, + svc.GetAntiSpamSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetAntiSpamSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateAntiSpamSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateAntiSpamSettingsProcedure, + svc.UpdateAntiSpamSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateAntiSpamSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetBanFooterSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetBanFooterSettingsProcedure, + svc.GetBanFooterSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetBanFooterSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateBanFooterSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateBanFooterSettingsProcedure, + svc.UpdateBanFooterSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateBanFooterSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetModmailSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetModmailSettingsProcedure, + svc.GetModmailSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModmailSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateModmailSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateModmailSettingsProcedure, + svc.UpdateModmailSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModmailSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceListChannelsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceListChannelsProcedure, + svc.ListChannels, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListChannels")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceListRolesHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceListRolesProcedure, + svc.ListRoles, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListRoles")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetTemplatePlaceholdersHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetTemplatePlaceholdersProcedure, + svc.GetTemplatePlaceholders, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetTemplatePlaceholders")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceSendComponentsMessageHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceSendComponentsMessageProcedure, + svc.SendComponentsMessage, + connect.WithSchema(guildSettingsServiceMethods.ByName("SendComponentsMessage")), + connect.WithHandlerOptions(opts...), + ) + return "/heimdallr.v1.GuildSettingsService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case GuildSettingsServiceGetModChannelProcedure: + guildSettingsServiceGetModChannelHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateModChannelProcedure: + guildSettingsServiceUpdateModChannelHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetInfractionSettingsProcedure: + guildSettingsServiceGetInfractionSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateInfractionSettingsProcedure: + guildSettingsServiceUpdateInfractionSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetGatekeepSettingsProcedure: + guildSettingsServiceGetGatekeepSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateGatekeepSettingsProcedure: + guildSettingsServiceUpdateGatekeepSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetJoinLeaveSettingsProcedure: + guildSettingsServiceGetJoinLeaveSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateJoinLeaveSettingsProcedure: + guildSettingsServiceUpdateJoinLeaveSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetAntiSpamSettingsProcedure: + guildSettingsServiceGetAntiSpamSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateAntiSpamSettingsProcedure: + guildSettingsServiceUpdateAntiSpamSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetBanFooterSettingsProcedure: + guildSettingsServiceGetBanFooterSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateBanFooterSettingsProcedure: + guildSettingsServiceUpdateBanFooterSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetModmailSettingsProcedure: + guildSettingsServiceGetModmailSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateModmailSettingsProcedure: + guildSettingsServiceUpdateModmailSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceListChannelsProcedure: + guildSettingsServiceListChannelsHandler.ServeHTTP(w, r) + case GuildSettingsServiceListRolesProcedure: + guildSettingsServiceListRolesHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetTemplatePlaceholdersProcedure: + guildSettingsServiceGetTemplatePlaceholdersHandler.ServeHTTP(w, r) + case GuildSettingsServiceSendComponentsMessageProcedure: + guildSettingsServiceSendComponentsMessageHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedGuildSettingsServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedGuildSettingsServiceHandler struct{} + +func (UnimplementedGuildSettingsServiceHandler) GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetModChannel is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateModChannel is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetInfractionSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateInfractionSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetGatekeepSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetAntiSpamSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetBanFooterSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetModmailSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateModmailSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.ListChannels is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.ListRoles is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.SendComponentsMessage is not implemented")) +} diff --git a/heimdallr/gen_/greet/v1/greet.pb.go b/heimdallr/gen_/greet/v1/greet.pb.go new file mode 100644 index 0000000..fed4a52 --- /dev/null +++ b/heimdallr/gen_/greet/v1/greet.pb.go @@ -0,0 +1,176 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: greet/v1/greet.proto + +package greetv1 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GreetRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GreetRequest) Reset() { + *x = GreetRequest{} + mi := &file_greet_v1_greet_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GreetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetRequest) ProtoMessage() {} + +func (x *GreetRequest) ProtoReflect() protoreflect.Message { + mi := &file_greet_v1_greet_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetRequest.ProtoReflect.Descriptor instead. +func (*GreetRequest) Descriptor() ([]byte, []int) { + return file_greet_v1_greet_proto_rawDescGZIP(), []int{0} +} + +func (x *GreetRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GreetResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GreetResponse) Reset() { + *x = GreetResponse{} + mi := &file_greet_v1_greet_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GreetResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetResponse) ProtoMessage() {} + +func (x *GreetResponse) ProtoReflect() protoreflect.Message { + mi := &file_greet_v1_greet_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetResponse.ProtoReflect.Descriptor instead. +func (*GreetResponse) Descriptor() ([]byte, []int) { + return file_greet_v1_greet_proto_rawDescGZIP(), []int{1} +} + +func (x *GreetResponse) GetGreeting() string { + if x != nil { + return x.Greeting + } + return "" +} + +var File_greet_v1_greet_proto protoreflect.FileDescriptor + +const file_greet_v1_greet_proto_rawDesc = "" + + "\n" + + "\x14greet/v1/greet.proto\x12\bgreet.v1\x1a\x1bbuf/validate/validate.proto\"-\n" + + "\fGreetRequest\x12\x1d\n" + + "\x04name\x18\x01 \x01(\tB\t\xbaH\x06r\x04\x10\x01\x182R\x04name\"+\n" + + "\rGreetResponse\x12\x1a\n" + + "\bgreeting\x18\x01 \x01(\tR\bgreeting2J\n" + + "\fGreetService\x12:\n" + + "\x05Greet\x12\x16.greet.v1.GreetRequest\x1a\x17.greet.v1.GreetResponse\"\x00B\x93\x01\n" + + "\fcom.greet.v1B\n" + + "GreetProtoP\x01Z6github.com/NLLCommunity/heimdallr/gen/greet/v1;greetv1\xa2\x02\x03GXX\xaa\x02\bGreet.V1\xca\x02\bGreet\\V1\xe2\x02\x14Greet\\V1\\GPBMetadata\xea\x02\tGreet::V1b\x06proto3" + +var ( + file_greet_v1_greet_proto_rawDescOnce sync.Once + file_greet_v1_greet_proto_rawDescData []byte +) + +func file_greet_v1_greet_proto_rawDescGZIP() []byte { + file_greet_v1_greet_proto_rawDescOnce.Do(func() { + file_greet_v1_greet_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_greet_v1_greet_proto_rawDesc), len(file_greet_v1_greet_proto_rawDesc))) + }) + return file_greet_v1_greet_proto_rawDescData +} + +var file_greet_v1_greet_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_greet_v1_greet_proto_goTypes = []any{ + (*GreetRequest)(nil), // 0: greet.v1.GreetRequest + (*GreetResponse)(nil), // 1: greet.v1.GreetResponse +} +var file_greet_v1_greet_proto_depIdxs = []int32{ + 0, // 0: greet.v1.GreetService.Greet:input_type -> greet.v1.GreetRequest + 1, // 1: greet.v1.GreetService.Greet:output_type -> greet.v1.GreetResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_greet_v1_greet_proto_init() } +func file_greet_v1_greet_proto_init() { + if File_greet_v1_greet_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_greet_v1_greet_proto_rawDesc), len(file_greet_v1_greet_proto_rawDesc)), + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_greet_v1_greet_proto_goTypes, + DependencyIndexes: file_greet_v1_greet_proto_depIdxs, + MessageInfos: file_greet_v1_greet_proto_msgTypes, + }.Build() + File_greet_v1_greet_proto = out.File + file_greet_v1_greet_proto_goTypes = nil + file_greet_v1_greet_proto_depIdxs = nil +} diff --git a/heimdallr/gen_/greet/v1/greetv1connect/greet.connect.go b/heimdallr/gen_/greet/v1/greetv1connect/greet.connect.go new file mode 100644 index 0000000..54db5d2 --- /dev/null +++ b/heimdallr/gen_/greet/v1/greetv1connect/greet.connect.go @@ -0,0 +1,112 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: greet/v1/greet.proto + +package greetv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/greet/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // GreetServiceName is the fully-qualified name of the GreetService service. + GreetServiceName = "greet.v1.GreetService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GreetServiceGreetProcedure is the fully-qualified name of the GreetService's Greet RPC. + GreetServiceGreetProcedure = "/greet.v1.GreetService/Greet" +) + +// GreetServiceClient is a client for the greet.v1.GreetService service. +type GreetServiceClient interface { + Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) +} + +// NewGreetServiceClient constructs a client for the greet.v1.GreetService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewGreetServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GreetServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + greetServiceMethods := v1.File_greet_v1_greet_proto.Services().ByName("GreetService").Methods() + return &greetServiceClient{ + greet: connect.NewClient[v1.GreetRequest, v1.GreetResponse]( + httpClient, + baseURL+GreetServiceGreetProcedure, + connect.WithSchema(greetServiceMethods.ByName("Greet")), + connect.WithClientOptions(opts...), + ), + } +} + +// greetServiceClient implements GreetServiceClient. +type greetServiceClient struct { + greet *connect.Client[v1.GreetRequest, v1.GreetResponse] +} + +// Greet calls greet.v1.GreetService.Greet. +func (c *greetServiceClient) Greet(ctx context.Context, req *v1.GreetRequest) (*v1.GreetResponse, error) { + response, err := c.greet.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GreetServiceHandler is an implementation of the greet.v1.GreetService service. +type GreetServiceHandler interface { + Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) +} + +// NewGreetServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewGreetServiceHandler(svc GreetServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + greetServiceMethods := v1.File_greet_v1_greet_proto.Services().ByName("GreetService").Methods() + greetServiceGreetHandler := connect.NewUnaryHandlerSimple( + GreetServiceGreetProcedure, + svc.Greet, + connect.WithSchema(greetServiceMethods.ByName("Greet")), + connect.WithHandlerOptions(opts...), + ) + return "/greet.v1.GreetService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case GreetServiceGreetProcedure: + greetServiceGreetHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedGreetServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedGreetServiceHandler struct{} + +func (UnimplementedGreetServiceHandler) Greet(context.Context, *v1.GreetRequest) (*v1.GreetResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("greet.v1.GreetService.Greet is not implemented")) +} diff --git a/heimdallr/gen_/heimdallr/v1/auth.pb.go b/heimdallr/gen_/heimdallr/v1/auth.pb.go new file mode 100644 index 0000000..be4ecd3 --- /dev/null +++ b/heimdallr/gen_/heimdallr/v1/auth.pb.go @@ -0,0 +1,651 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: heimdallr/v1/auth.proto + +package heimdallrv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type User struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *User) Reset() { + *x = User{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *User) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +type Guild struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Icon string `protobuf:"bytes,3,opt,name=icon,proto3" json:"icon,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Guild) Reset() { + *x = Guild{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Guild) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Guild) ProtoMessage() {} + +func (x *Guild) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Guild.ProtoReflect.Descriptor instead. +func (*Guild) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{1} +} + +func (x *Guild) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Guild) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Guild) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +type GetLoginURLRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetLoginURLRequest) Reset() { + *x = GetLoginURLRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetLoginURLRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLoginURLRequest) ProtoMessage() {} + +func (x *GetLoginURLRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLoginURLRequest.ProtoReflect.Descriptor instead. +func (*GetLoginURLRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{2} +} + +type GetLoginURLResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetLoginURLResponse) Reset() { + *x = GetLoginURLResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetLoginURLResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLoginURLResponse) ProtoMessage() {} + +func (x *GetLoginURLResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLoginURLResponse.ProtoReflect.Descriptor instead. +func (*GetLoginURLResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{3} +} + +func (x *GetLoginURLResponse) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type ExchangeCodeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExchangeCodeRequest) Reset() { + *x = ExchangeCodeRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExchangeCodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExchangeCodeRequest) ProtoMessage() {} + +func (x *ExchangeCodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExchangeCodeRequest.ProtoReflect.Descriptor instead. +func (*ExchangeCodeRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{4} +} + +func (x *ExchangeCodeRequest) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +type ExchangeCodeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExchangeCodeResponse) Reset() { + *x = ExchangeCodeResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExchangeCodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExchangeCodeResponse) ProtoMessage() {} + +func (x *ExchangeCodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExchangeCodeResponse.ProtoReflect.Descriptor instead. +func (*ExchangeCodeResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{5} +} + +func (x *ExchangeCodeResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type GetCurrentUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCurrentUserRequest) Reset() { + *x = GetCurrentUserRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCurrentUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentUserRequest) ProtoMessage() {} + +func (x *GetCurrentUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCurrentUserRequest.ProtoReflect.Descriptor instead. +func (*GetCurrentUserRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{6} +} + +type GetCurrentUserResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCurrentUserResponse) Reset() { + *x = GetCurrentUserResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCurrentUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentUserResponse) ProtoMessage() {} + +func (x *GetCurrentUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCurrentUserResponse.ProtoReflect.Descriptor instead. +func (*GetCurrentUserResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{7} +} + +func (x *GetCurrentUserResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type ListGuildsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListGuildsRequest) Reset() { + *x = ListGuildsRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListGuildsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListGuildsRequest) ProtoMessage() {} + +func (x *ListGuildsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListGuildsRequest.ProtoReflect.Descriptor instead. +func (*ListGuildsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{8} +} + +type ListGuildsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Guilds []*Guild `protobuf:"bytes,1,rep,name=guilds,proto3" json:"guilds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListGuildsResponse) Reset() { + *x = ListGuildsResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListGuildsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListGuildsResponse) ProtoMessage() {} + +func (x *ListGuildsResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListGuildsResponse.ProtoReflect.Descriptor instead. +func (*ListGuildsResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{9} +} + +func (x *ListGuildsResponse) GetGuilds() []*Guild { + if x != nil { + return x.Guilds + } + return nil +} + +type LogoutRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogoutRequest) Reset() { + *x = LogoutRequest{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutRequest) ProtoMessage() {} + +func (x *LogoutRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. +func (*LogoutRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{10} +} + +type LogoutResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogoutResponse) Reset() { + *x = LogoutResponse{} + mi := &file_heimdallr_v1_auth_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutResponse) ProtoMessage() {} + +func (x *LogoutResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_auth_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead. +func (*LogoutResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_auth_proto_rawDescGZIP(), []int{11} +} + +var File_heimdallr_v1_auth_proto protoreflect.FileDescriptor + +const file_heimdallr_v1_auth_proto_rawDesc = "" + + "\n" + + "\x17heimdallr/v1/auth.proto\x12\fheimdallr.v1\"J\n" + + "\x04User\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" + + "\busername\x18\x02 \x01(\tR\busername\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\"?\n" + + "\x05Guild\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04icon\x18\x03 \x01(\tR\x04icon\"\x14\n" + + "\x12GetLoginURLRequest\"'\n" + + "\x13GetLoginURLResponse\x12\x10\n" + + "\x03url\x18\x01 \x01(\tR\x03url\")\n" + + "\x13ExchangeCodeRequest\x12\x12\n" + + "\x04code\x18\x01 \x01(\tR\x04code\">\n" + + "\x14ExchangeCodeResponse\x12&\n" + + "\x04user\x18\x02 \x01(\v2\x12.heimdallr.v1.UserR\x04user\"\x17\n" + + "\x15GetCurrentUserRequest\"@\n" + + "\x16GetCurrentUserResponse\x12&\n" + + "\x04user\x18\x01 \x01(\v2\x12.heimdallr.v1.UserR\x04user\"\x13\n" + + "\x11ListGuildsRequest\"A\n" + + "\x12ListGuildsResponse\x12+\n" + + "\x06guilds\x18\x01 \x03(\v2\x13.heimdallr.v1.GuildR\x06guilds\"\x0f\n" + + "\rLogoutRequest\"\x10\n" + + "\x0eLogoutResponse2\xab\x03\n" + + "\vAuthService\x12R\n" + + "\vGetLoginURL\x12 .heimdallr.v1.GetLoginURLRequest\x1a!.heimdallr.v1.GetLoginURLResponse\x12U\n" + + "\fExchangeCode\x12!.heimdallr.v1.ExchangeCodeRequest\x1a\".heimdallr.v1.ExchangeCodeResponse\x12[\n" + + "\x0eGetCurrentUser\x12#.heimdallr.v1.GetCurrentUserRequest\x1a$.heimdallr.v1.GetCurrentUserResponse\x12O\n" + + "\n" + + "ListGuilds\x12\x1f.heimdallr.v1.ListGuildsRequest\x1a .heimdallr.v1.ListGuildsResponse\x12C\n" + + "\x06Logout\x12\x1b.heimdallr.v1.LogoutRequest\x1a\x1c.heimdallr.v1.LogoutResponseB\xae\x01\n" + + "\x10com.heimdallr.v1B\tAuthProtoP\x01Z>github.com/NLLCommunity/heimdallr/gen/heimdallr/v1;heimdallrv1\xa2\x02\x03HXX\xaa\x02\fHeimdallr.V1\xca\x02\fHeimdallr\\V1\xe2\x02\x18Heimdallr\\V1\\GPBMetadata\xea\x02\rHeimdallr::V1b\x06proto3" + +var ( + file_heimdallr_v1_auth_proto_rawDescOnce sync.Once + file_heimdallr_v1_auth_proto_rawDescData []byte +) + +func file_heimdallr_v1_auth_proto_rawDescGZIP() []byte { + file_heimdallr_v1_auth_proto_rawDescOnce.Do(func() { + file_heimdallr_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_heimdallr_v1_auth_proto_rawDesc), len(file_heimdallr_v1_auth_proto_rawDesc))) + }) + return file_heimdallr_v1_auth_proto_rawDescData +} + +var file_heimdallr_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_heimdallr_v1_auth_proto_goTypes = []any{ + (*User)(nil), // 0: heimdallr.v1.User + (*Guild)(nil), // 1: heimdallr.v1.Guild + (*GetLoginURLRequest)(nil), // 2: heimdallr.v1.GetLoginURLRequest + (*GetLoginURLResponse)(nil), // 3: heimdallr.v1.GetLoginURLResponse + (*ExchangeCodeRequest)(nil), // 4: heimdallr.v1.ExchangeCodeRequest + (*ExchangeCodeResponse)(nil), // 5: heimdallr.v1.ExchangeCodeResponse + (*GetCurrentUserRequest)(nil), // 6: heimdallr.v1.GetCurrentUserRequest + (*GetCurrentUserResponse)(nil), // 7: heimdallr.v1.GetCurrentUserResponse + (*ListGuildsRequest)(nil), // 8: heimdallr.v1.ListGuildsRequest + (*ListGuildsResponse)(nil), // 9: heimdallr.v1.ListGuildsResponse + (*LogoutRequest)(nil), // 10: heimdallr.v1.LogoutRequest + (*LogoutResponse)(nil), // 11: heimdallr.v1.LogoutResponse +} +var file_heimdallr_v1_auth_proto_depIdxs = []int32{ + 0, // 0: heimdallr.v1.ExchangeCodeResponse.user:type_name -> heimdallr.v1.User + 0, // 1: heimdallr.v1.GetCurrentUserResponse.user:type_name -> heimdallr.v1.User + 1, // 2: heimdallr.v1.ListGuildsResponse.guilds:type_name -> heimdallr.v1.Guild + 2, // 3: heimdallr.v1.AuthService.GetLoginURL:input_type -> heimdallr.v1.GetLoginURLRequest + 4, // 4: heimdallr.v1.AuthService.ExchangeCode:input_type -> heimdallr.v1.ExchangeCodeRequest + 6, // 5: heimdallr.v1.AuthService.GetCurrentUser:input_type -> heimdallr.v1.GetCurrentUserRequest + 8, // 6: heimdallr.v1.AuthService.ListGuilds:input_type -> heimdallr.v1.ListGuildsRequest + 10, // 7: heimdallr.v1.AuthService.Logout:input_type -> heimdallr.v1.LogoutRequest + 3, // 8: heimdallr.v1.AuthService.GetLoginURL:output_type -> heimdallr.v1.GetLoginURLResponse + 5, // 9: heimdallr.v1.AuthService.ExchangeCode:output_type -> heimdallr.v1.ExchangeCodeResponse + 7, // 10: heimdallr.v1.AuthService.GetCurrentUser:output_type -> heimdallr.v1.GetCurrentUserResponse + 9, // 11: heimdallr.v1.AuthService.ListGuilds:output_type -> heimdallr.v1.ListGuildsResponse + 11, // 12: heimdallr.v1.AuthService.Logout:output_type -> heimdallr.v1.LogoutResponse + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_heimdallr_v1_auth_proto_init() } +func file_heimdallr_v1_auth_proto_init() { + if File_heimdallr_v1_auth_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_heimdallr_v1_auth_proto_rawDesc), len(file_heimdallr_v1_auth_proto_rawDesc)), + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_heimdallr_v1_auth_proto_goTypes, + DependencyIndexes: file_heimdallr_v1_auth_proto_depIdxs, + MessageInfos: file_heimdallr_v1_auth_proto_msgTypes, + }.Build() + File_heimdallr_v1_auth_proto = out.File + file_heimdallr_v1_auth_proto_goTypes = nil + file_heimdallr_v1_auth_proto_depIdxs = nil +} diff --git a/heimdallr/gen_/heimdallr/v1/guild_settings.pb.go b/heimdallr/gen_/heimdallr/v1/guild_settings.pb.go new file mode 100644 index 0000000..b936723 --- /dev/null +++ b/heimdallr/gen_/heimdallr/v1/guild_settings.pb.go @@ -0,0 +1,2001 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: heimdallr/v1/guild_settings.proto + +package heimdallrv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ModChannel +type GetModChannelRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetModChannelRequest) Reset() { + *x = GetModChannelRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetModChannelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModChannelRequest) ProtoMessage() {} + +func (x *GetModChannelRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModChannelRequest.ProtoReflect.Descriptor instead. +func (*GetModChannelRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{0} +} + +func (x *GetModChannelRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateModChannelRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *ModChannelSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateModChannelRequest) Reset() { + *x = UpdateModChannelRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateModChannelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModChannelRequest) ProtoMessage() {} + +func (x *UpdateModChannelRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModChannelRequest.ProtoReflect.Descriptor instead. +func (*UpdateModChannelRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateModChannelRequest) GetSettings() *ModChannelSettings { + if x != nil { + return x.Settings + } + return nil +} + +type ModChannelSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ModeratorChannel string `protobuf:"bytes,2,opt,name=moderator_channel,json=moderatorChannel,proto3" json:"moderator_channel,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ModChannelSettings) Reset() { + *x = ModChannelSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ModChannelSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModChannelSettings) ProtoMessage() {} + +func (x *ModChannelSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModChannelSettings.ProtoReflect.Descriptor instead. +func (*ModChannelSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{2} +} + +func (x *ModChannelSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *ModChannelSettings) GetModeratorChannel() string { + if x != nil { + return x.ModeratorChannel + } + return "" +} + +// InfractionSettings +type GetInfractionSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInfractionSettingsRequest) Reset() { + *x = GetInfractionSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInfractionSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfractionSettingsRequest) ProtoMessage() {} + +func (x *GetInfractionSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfractionSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetInfractionSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{3} +} + +func (x *GetInfractionSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateInfractionSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *InfractionSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateInfractionSettingsRequest) Reset() { + *x = UpdateInfractionSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateInfractionSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateInfractionSettingsRequest) ProtoMessage() {} + +func (x *UpdateInfractionSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateInfractionSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateInfractionSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateInfractionSettingsRequest) GetSettings() *InfractionSettings { + if x != nil { + return x.Settings + } + return nil +} + +type InfractionSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + HalfLifeDays float64 `protobuf:"fixed64,2,opt,name=half_life_days,json=halfLifeDays,proto3" json:"half_life_days,omitempty"` + NotifyOnWarnedUserJoin bool `protobuf:"varint,3,opt,name=notify_on_warned_user_join,json=notifyOnWarnedUserJoin,proto3" json:"notify_on_warned_user_join,omitempty"` + NotifyWarnSeverityThreshold float64 `protobuf:"fixed64,4,opt,name=notify_warn_severity_threshold,json=notifyWarnSeverityThreshold,proto3" json:"notify_warn_severity_threshold,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InfractionSettings) Reset() { + *x = InfractionSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InfractionSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfractionSettings) ProtoMessage() {} + +func (x *InfractionSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InfractionSettings.ProtoReflect.Descriptor instead. +func (*InfractionSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{5} +} + +func (x *InfractionSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *InfractionSettings) GetHalfLifeDays() float64 { + if x != nil { + return x.HalfLifeDays + } + return 0 +} + +func (x *InfractionSettings) GetNotifyOnWarnedUserJoin() bool { + if x != nil { + return x.NotifyOnWarnedUserJoin + } + return false +} + +func (x *InfractionSettings) GetNotifyWarnSeverityThreshold() float64 { + if x != nil { + return x.NotifyWarnSeverityThreshold + } + return 0 +} + +// GatekeepSettings +type GetGatekeepSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetGatekeepSettingsRequest) Reset() { + *x = GetGatekeepSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetGatekeepSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetGatekeepSettingsRequest) ProtoMessage() {} + +func (x *GetGatekeepSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetGatekeepSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetGatekeepSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{6} +} + +func (x *GetGatekeepSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateGatekeepSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *GatekeepSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateGatekeepSettingsRequest) Reset() { + *x = UpdateGatekeepSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateGatekeepSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateGatekeepSettingsRequest) ProtoMessage() {} + +func (x *UpdateGatekeepSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateGatekeepSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateGatekeepSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateGatekeepSettingsRequest) GetSettings() *GatekeepSettings { + if x != nil { + return x.Settings + } + return nil +} + +type GatekeepSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + PendingRole string `protobuf:"bytes,3,opt,name=pending_role,json=pendingRole,proto3" json:"pending_role,omitempty"` + ApprovedRole string `protobuf:"bytes,4,opt,name=approved_role,json=approvedRole,proto3" json:"approved_role,omitempty"` + AddPendingRoleOnJoin bool `protobuf:"varint,5,opt,name=add_pending_role_on_join,json=addPendingRoleOnJoin,proto3" json:"add_pending_role_on_join,omitempty"` + ApprovedMessage string `protobuf:"bytes,6,opt,name=approved_message,json=approvedMessage,proto3" json:"approved_message,omitempty"` + ApprovedMessageV2 bool `protobuf:"varint,7,opt,name=approved_message_v2,json=approvedMessageV2,proto3" json:"approved_message_v2,omitempty"` + ApprovedMessageV2Json string `protobuf:"bytes,8,opt,name=approved_message_v2_json,json=approvedMessageV2Json,proto3" json:"approved_message_v2_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GatekeepSettings) Reset() { + *x = GatekeepSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GatekeepSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GatekeepSettings) ProtoMessage() {} + +func (x *GatekeepSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GatekeepSettings.ProtoReflect.Descriptor instead. +func (*GatekeepSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{8} +} + +func (x *GatekeepSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *GatekeepSettings) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *GatekeepSettings) GetPendingRole() string { + if x != nil { + return x.PendingRole + } + return "" +} + +func (x *GatekeepSettings) GetApprovedRole() string { + if x != nil { + return x.ApprovedRole + } + return "" +} + +func (x *GatekeepSettings) GetAddPendingRoleOnJoin() bool { + if x != nil { + return x.AddPendingRoleOnJoin + } + return false +} + +func (x *GatekeepSettings) GetApprovedMessage() string { + if x != nil { + return x.ApprovedMessage + } + return "" +} + +func (x *GatekeepSettings) GetApprovedMessageV2() bool { + if x != nil { + return x.ApprovedMessageV2 + } + return false +} + +func (x *GatekeepSettings) GetApprovedMessageV2Json() string { + if x != nil { + return x.ApprovedMessageV2Json + } + return "" +} + +// JoinLeaveSettings +type GetJoinLeaveSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetJoinLeaveSettingsRequest) Reset() { + *x = GetJoinLeaveSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetJoinLeaveSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJoinLeaveSettingsRequest) ProtoMessage() {} + +func (x *GetJoinLeaveSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJoinLeaveSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetJoinLeaveSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{9} +} + +func (x *GetJoinLeaveSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateJoinLeaveSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *JoinLeaveSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateJoinLeaveSettingsRequest) Reset() { + *x = UpdateJoinLeaveSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateJoinLeaveSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateJoinLeaveSettingsRequest) ProtoMessage() {} + +func (x *UpdateJoinLeaveSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateJoinLeaveSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateJoinLeaveSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateJoinLeaveSettingsRequest) GetSettings() *JoinLeaveSettings { + if x != nil { + return x.Settings + } + return nil +} + +type JoinLeaveSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + JoinMessageEnabled bool `protobuf:"varint,2,opt,name=join_message_enabled,json=joinMessageEnabled,proto3" json:"join_message_enabled,omitempty"` + JoinMessage string `protobuf:"bytes,3,opt,name=join_message,json=joinMessage,proto3" json:"join_message,omitempty"` + LeaveMessageEnabled bool `protobuf:"varint,4,opt,name=leave_message_enabled,json=leaveMessageEnabled,proto3" json:"leave_message_enabled,omitempty"` + LeaveMessage string `protobuf:"bytes,5,opt,name=leave_message,json=leaveMessage,proto3" json:"leave_message,omitempty"` + Channel string `protobuf:"bytes,6,opt,name=channel,proto3" json:"channel,omitempty"` + JoinMessageV2 bool `protobuf:"varint,7,opt,name=join_message_v2,json=joinMessageV2,proto3" json:"join_message_v2,omitempty"` + JoinMessageV2Json string `protobuf:"bytes,8,opt,name=join_message_v2_json,json=joinMessageV2Json,proto3" json:"join_message_v2_json,omitempty"` + LeaveMessageV2 bool `protobuf:"varint,9,opt,name=leave_message_v2,json=leaveMessageV2,proto3" json:"leave_message_v2,omitempty"` + LeaveMessageV2Json string `protobuf:"bytes,10,opt,name=leave_message_v2_json,json=leaveMessageV2Json,proto3" json:"leave_message_v2_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JoinLeaveSettings) Reset() { + *x = JoinLeaveSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JoinLeaveSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JoinLeaveSettings) ProtoMessage() {} + +func (x *JoinLeaveSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JoinLeaveSettings.ProtoReflect.Descriptor instead. +func (*JoinLeaveSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{11} +} + +func (x *JoinLeaveSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *JoinLeaveSettings) GetJoinMessageEnabled() bool { + if x != nil { + return x.JoinMessageEnabled + } + return false +} + +func (x *JoinLeaveSettings) GetJoinMessage() string { + if x != nil { + return x.JoinMessage + } + return "" +} + +func (x *JoinLeaveSettings) GetLeaveMessageEnabled() bool { + if x != nil { + return x.LeaveMessageEnabled + } + return false +} + +func (x *JoinLeaveSettings) GetLeaveMessage() string { + if x != nil { + return x.LeaveMessage + } + return "" +} + +func (x *JoinLeaveSettings) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *JoinLeaveSettings) GetJoinMessageV2() bool { + if x != nil { + return x.JoinMessageV2 + } + return false +} + +func (x *JoinLeaveSettings) GetJoinMessageV2Json() string { + if x != nil { + return x.JoinMessageV2Json + } + return "" +} + +func (x *JoinLeaveSettings) GetLeaveMessageV2() bool { + if x != nil { + return x.LeaveMessageV2 + } + return false +} + +func (x *JoinLeaveSettings) GetLeaveMessageV2Json() string { + if x != nil { + return x.LeaveMessageV2Json + } + return "" +} + +// AntiSpamSettings +type GetAntiSpamSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAntiSpamSettingsRequest) Reset() { + *x = GetAntiSpamSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAntiSpamSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAntiSpamSettingsRequest) ProtoMessage() {} + +func (x *GetAntiSpamSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAntiSpamSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetAntiSpamSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{12} +} + +func (x *GetAntiSpamSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateAntiSpamSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *AntiSpamSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateAntiSpamSettingsRequest) Reset() { + *x = UpdateAntiSpamSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateAntiSpamSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAntiSpamSettingsRequest) ProtoMessage() {} + +func (x *UpdateAntiSpamSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAntiSpamSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateAntiSpamSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{13} +} + +func (x *UpdateAntiSpamSettingsRequest) GetSettings() *AntiSpamSettings { + if x != nil { + return x.Settings + } + return nil +} + +type AntiSpamSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + Count int32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` + CooldownSeconds int32 `protobuf:"varint,4,opt,name=cooldown_seconds,json=cooldownSeconds,proto3" json:"cooldown_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AntiSpamSettings) Reset() { + *x = AntiSpamSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AntiSpamSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AntiSpamSettings) ProtoMessage() {} + +func (x *AntiSpamSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AntiSpamSettings.ProtoReflect.Descriptor instead. +func (*AntiSpamSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{14} +} + +func (x *AntiSpamSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *AntiSpamSettings) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *AntiSpamSettings) GetCount() int32 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *AntiSpamSettings) GetCooldownSeconds() int32 { + if x != nil { + return x.CooldownSeconds + } + return 0 +} + +// BanFooterSettings +type GetBanFooterSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetBanFooterSettingsRequest) Reset() { + *x = GetBanFooterSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetBanFooterSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBanFooterSettingsRequest) ProtoMessage() {} + +func (x *GetBanFooterSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBanFooterSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetBanFooterSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBanFooterSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateBanFooterSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *BanFooterSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateBanFooterSettingsRequest) Reset() { + *x = UpdateBanFooterSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateBanFooterSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBanFooterSettingsRequest) ProtoMessage() {} + +func (x *UpdateBanFooterSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateBanFooterSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateBanFooterSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{16} +} + +func (x *UpdateBanFooterSettingsRequest) GetSettings() *BanFooterSettings { + if x != nil { + return x.Settings + } + return nil +} + +type BanFooterSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + Footer string `protobuf:"bytes,2,opt,name=footer,proto3" json:"footer,omitempty"` + AlwaysSend bool `protobuf:"varint,3,opt,name=always_send,json=alwaysSend,proto3" json:"always_send,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BanFooterSettings) Reset() { + *x = BanFooterSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BanFooterSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BanFooterSettings) ProtoMessage() {} + +func (x *BanFooterSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BanFooterSettings.ProtoReflect.Descriptor instead. +func (*BanFooterSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{17} +} + +func (x *BanFooterSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *BanFooterSettings) GetFooter() string { + if x != nil { + return x.Footer + } + return "" +} + +func (x *BanFooterSettings) GetAlwaysSend() bool { + if x != nil { + return x.AlwaysSend + } + return false +} + +// ModmailSettings +type GetModmailSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetModmailSettingsRequest) Reset() { + *x = GetModmailSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetModmailSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModmailSettingsRequest) ProtoMessage() {} + +func (x *GetModmailSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModmailSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetModmailSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{18} +} + +func (x *GetModmailSettingsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type UpdateModmailSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Settings *ModmailSettings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateModmailSettingsRequest) Reset() { + *x = UpdateModmailSettingsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateModmailSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModmailSettingsRequest) ProtoMessage() {} + +func (x *UpdateModmailSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModmailSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateModmailSettingsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{19} +} + +func (x *UpdateModmailSettingsRequest) GetSettings() *ModmailSettings { + if x != nil { + return x.Settings + } + return nil +} + +type ModmailSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ReportThreadsChannel string `protobuf:"bytes,2,opt,name=report_threads_channel,json=reportThreadsChannel,proto3" json:"report_threads_channel,omitempty"` + ReportNotificationChannel string `protobuf:"bytes,3,opt,name=report_notification_channel,json=reportNotificationChannel,proto3" json:"report_notification_channel,omitempty"` + ReportPingRole string `protobuf:"bytes,4,opt,name=report_ping_role,json=reportPingRole,proto3" json:"report_ping_role,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ModmailSettings) Reset() { + *x = ModmailSettings{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ModmailSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModmailSettings) ProtoMessage() {} + +func (x *ModmailSettings) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModmailSettings.ProtoReflect.Descriptor instead. +func (*ModmailSettings) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{20} +} + +func (x *ModmailSettings) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *ModmailSettings) GetReportThreadsChannel() string { + if x != nil { + return x.ReportThreadsChannel + } + return "" +} + +func (x *ModmailSettings) GetReportNotificationChannel() string { + if x != nil { + return x.ReportNotificationChannel + } + return "" +} + +func (x *ModmailSettings) GetReportPingRole() string { + if x != nil { + return x.ReportPingRole + } + return "" +} + +// Guild data (channels & roles) +type Channel struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Type int32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"` + Position int32 `protobuf:"varint,4,opt,name=position,proto3" json:"position,omitempty"` + ParentId string `protobuf:"bytes,5,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Channel) Reset() { + *x = Channel{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Channel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Channel) ProtoMessage() {} + +func (x *Channel) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Channel.ProtoReflect.Descriptor instead. +func (*Channel) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{21} +} + +func (x *Channel) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Channel) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Channel) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *Channel) GetPosition() int32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *Channel) GetParentId() string { + if x != nil { + return x.ParentId + } + return "" +} + +type Role struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Color int32 `protobuf:"varint,3,opt,name=color,proto3" json:"color,omitempty"` + Position int32 `protobuf:"varint,4,opt,name=position,proto3" json:"position,omitempty"` + Managed bool `protobuf:"varint,5,opt,name=managed,proto3" json:"managed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Role) Reset() { + *x = Role{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Role) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Role) ProtoMessage() {} + +func (x *Role) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Role.ProtoReflect.Descriptor instead. +func (*Role) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{22} +} + +func (x *Role) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Role) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Role) GetColor() int32 { + if x != nil { + return x.Color + } + return 0 +} + +func (x *Role) GetPosition() int32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *Role) GetManaged() bool { + if x != nil { + return x.Managed + } + return false +} + +type ListChannelsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListChannelsRequest) Reset() { + *x = ListChannelsRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListChannelsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListChannelsRequest) ProtoMessage() {} + +func (x *ListChannelsRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListChannelsRequest.ProtoReflect.Descriptor instead. +func (*ListChannelsRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{23} +} + +func (x *ListChannelsRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type ListChannelsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Channels []*Channel `protobuf:"bytes,1,rep,name=channels,proto3" json:"channels,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListChannelsResponse) Reset() { + *x = ListChannelsResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListChannelsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListChannelsResponse) ProtoMessage() {} + +func (x *ListChannelsResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListChannelsResponse.ProtoReflect.Descriptor instead. +func (*ListChannelsResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{24} +} + +func (x *ListChannelsResponse) GetChannels() []*Channel { + if x != nil { + return x.Channels + } + return nil +} + +type ListRolesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListRolesRequest) Reset() { + *x = ListRolesRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListRolesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesRequest) ProtoMessage() {} + +func (x *ListRolesRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesRequest.ProtoReflect.Descriptor instead. +func (*ListRolesRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{25} +} + +func (x *ListRolesRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +type ListRolesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Roles []*Role `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListRolesResponse) Reset() { + *x = ListRolesResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListRolesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesResponse) ProtoMessage() {} + +func (x *ListRolesResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesResponse.ProtoReflect.Descriptor instead. +func (*ListRolesResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{26} +} + +func (x *ListRolesResponse) GetRoles() []*Role { + if x != nil { + return x.Roles + } + return nil +} + +// SendComponentsMessage +type SendComponentsMessageRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + GuildId string `protobuf:"bytes,1,opt,name=guild_id,json=guildId,proto3" json:"guild_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + ComponentsJson string `protobuf:"bytes,3,opt,name=components_json,json=componentsJson,proto3" json:"components_json,omitempty"` // JSON array of discord LayoutComponents + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendComponentsMessageRequest) Reset() { + *x = SendComponentsMessageRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendComponentsMessageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendComponentsMessageRequest) ProtoMessage() {} + +func (x *SendComponentsMessageRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendComponentsMessageRequest.ProtoReflect.Descriptor instead. +func (*SendComponentsMessageRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{27} +} + +func (x *SendComponentsMessageRequest) GetGuildId() string { + if x != nil { + return x.GuildId + } + return "" +} + +func (x *SendComponentsMessageRequest) GetChannelId() string { + if x != nil { + return x.ChannelId + } + return "" +} + +func (x *SendComponentsMessageRequest) GetComponentsJson() string { + if x != nil { + return x.ComponentsJson + } + return "" +} + +type SendComponentsMessageResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + MessageId string `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendComponentsMessageResponse) Reset() { + *x = SendComponentsMessageResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendComponentsMessageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendComponentsMessageResponse) ProtoMessage() {} + +func (x *SendComponentsMessageResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendComponentsMessageResponse.ProtoReflect.Descriptor instead. +func (*SendComponentsMessageResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{28} +} + +func (x *SendComponentsMessageResponse) GetMessageId() string { + if x != nil { + return x.MessageId + } + return "" +} + +// Template placeholders +type TemplatePlaceholder struct { + state protoimpl.MessageState `protogen:"open.v1"` + Placeholder string `protobuf:"bytes,1,opt,name=placeholder,proto3" json:"placeholder,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TemplatePlaceholder) Reset() { + *x = TemplatePlaceholder{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TemplatePlaceholder) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplatePlaceholder) ProtoMessage() {} + +func (x *TemplatePlaceholder) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TemplatePlaceholder.ProtoReflect.Descriptor instead. +func (*TemplatePlaceholder) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{29} +} + +func (x *TemplatePlaceholder) GetPlaceholder() string { + if x != nil { + return x.Placeholder + } + return "" +} + +func (x *TemplatePlaceholder) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +type GetTemplatePlaceholdersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTemplatePlaceholdersRequest) Reset() { + *x = GetTemplatePlaceholdersRequest{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTemplatePlaceholdersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTemplatePlaceholdersRequest) ProtoMessage() {} + +func (x *GetTemplatePlaceholdersRequest) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTemplatePlaceholdersRequest.ProtoReflect.Descriptor instead. +func (*GetTemplatePlaceholdersRequest) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{30} +} + +type GetTemplatePlaceholdersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Placeholders []*TemplatePlaceholder `protobuf:"bytes,1,rep,name=placeholders,proto3" json:"placeholders,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTemplatePlaceholdersResponse) Reset() { + *x = GetTemplatePlaceholdersResponse{} + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTemplatePlaceholdersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTemplatePlaceholdersResponse) ProtoMessage() {} + +func (x *GetTemplatePlaceholdersResponse) ProtoReflect() protoreflect.Message { + mi := &file_heimdallr_v1_guild_settings_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTemplatePlaceholdersResponse.ProtoReflect.Descriptor instead. +func (*GetTemplatePlaceholdersResponse) Descriptor() ([]byte, []int) { + return file_heimdallr_v1_guild_settings_proto_rawDescGZIP(), []int{31} +} + +func (x *GetTemplatePlaceholdersResponse) GetPlaceholders() []*TemplatePlaceholder { + if x != nil { + return x.Placeholders + } + return nil +} + +var File_heimdallr_v1_guild_settings_proto protoreflect.FileDescriptor + +const file_heimdallr_v1_guild_settings_proto_rawDesc = "" + + "\n" + + "!heimdallr/v1/guild_settings.proto\x12\fheimdallr.v1\"1\n" + + "\x14GetModChannelRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"W\n" + + "\x17UpdateModChannelRequest\x12<\n" + + "\bsettings\x18\x01 \x01(\v2 .heimdallr.v1.ModChannelSettingsR\bsettings\"\\\n" + + "\x12ModChannelSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12+\n" + + "\x11moderator_channel\x18\x02 \x01(\tR\x10moderatorChannel\"9\n" + + "\x1cGetInfractionSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"_\n" + + "\x1fUpdateInfractionSettingsRequest\x12<\n" + + "\bsettings\x18\x01 \x01(\v2 .heimdallr.v1.InfractionSettingsR\bsettings\"\xd6\x01\n" + + "\x12InfractionSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12$\n" + + "\x0ehalf_life_days\x18\x02 \x01(\x01R\fhalfLifeDays\x12:\n" + + "\x1anotify_on_warned_user_join\x18\x03 \x01(\bR\x16notifyOnWarnedUserJoin\x12C\n" + + "\x1enotify_warn_severity_threshold\x18\x04 \x01(\x01R\x1bnotifyWarnSeverityThreshold\"7\n" + + "\x1aGetGatekeepSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"[\n" + + "\x1dUpdateGatekeepSettingsRequest\x12:\n" + + "\bsettings\x18\x01 \x01(\v2\x1e.heimdallr.v1.GatekeepSettingsR\bsettings\"\xdb\x02\n" + + "\x10GatekeepSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x18\n" + + "\aenabled\x18\x02 \x01(\bR\aenabled\x12!\n" + + "\fpending_role\x18\x03 \x01(\tR\vpendingRole\x12#\n" + + "\rapproved_role\x18\x04 \x01(\tR\fapprovedRole\x126\n" + + "\x18add_pending_role_on_join\x18\x05 \x01(\bR\x14addPendingRoleOnJoin\x12)\n" + + "\x10approved_message\x18\x06 \x01(\tR\x0fapprovedMessage\x12.\n" + + "\x13approved_message_v2\x18\a \x01(\bR\x11approvedMessageV2\x127\n" + + "\x18approved_message_v2_json\x18\b \x01(\tR\x15approvedMessageV2Json\"8\n" + + "\x1bGetJoinLeaveSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"]\n" + + "\x1eUpdateJoinLeaveSettingsRequest\x12;\n" + + "\bsettings\x18\x01 \x01(\v2\x1f.heimdallr.v1.JoinLeaveSettingsR\bsettings\"\xac\x03\n" + + "\x11JoinLeaveSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x120\n" + + "\x14join_message_enabled\x18\x02 \x01(\bR\x12joinMessageEnabled\x12!\n" + + "\fjoin_message\x18\x03 \x01(\tR\vjoinMessage\x122\n" + + "\x15leave_message_enabled\x18\x04 \x01(\bR\x13leaveMessageEnabled\x12#\n" + + "\rleave_message\x18\x05 \x01(\tR\fleaveMessage\x12\x18\n" + + "\achannel\x18\x06 \x01(\tR\achannel\x12&\n" + + "\x0fjoin_message_v2\x18\a \x01(\bR\rjoinMessageV2\x12/\n" + + "\x14join_message_v2_json\x18\b \x01(\tR\x11joinMessageV2Json\x12(\n" + + "\x10leave_message_v2\x18\t \x01(\bR\x0eleaveMessageV2\x121\n" + + "\x15leave_message_v2_json\x18\n" + + " \x01(\tR\x12leaveMessageV2Json\"7\n" + + "\x1aGetAntiSpamSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"[\n" + + "\x1dUpdateAntiSpamSettingsRequest\x12:\n" + + "\bsettings\x18\x01 \x01(\v2\x1e.heimdallr.v1.AntiSpamSettingsR\bsettings\"\x88\x01\n" + + "\x10AntiSpamSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x18\n" + + "\aenabled\x18\x02 \x01(\bR\aenabled\x12\x14\n" + + "\x05count\x18\x03 \x01(\x05R\x05count\x12)\n" + + "\x10cooldown_seconds\x18\x04 \x01(\x05R\x0fcooldownSeconds\"8\n" + + "\x1bGetBanFooterSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"]\n" + + "\x1eUpdateBanFooterSettingsRequest\x12;\n" + + "\bsettings\x18\x01 \x01(\v2\x1f.heimdallr.v1.BanFooterSettingsR\bsettings\"g\n" + + "\x11BanFooterSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x16\n" + + "\x06footer\x18\x02 \x01(\tR\x06footer\x12\x1f\n" + + "\valways_send\x18\x03 \x01(\bR\n" + + "alwaysSend\"6\n" + + "\x19GetModmailSettingsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"Y\n" + + "\x1cUpdateModmailSettingsRequest\x129\n" + + "\bsettings\x18\x01 \x01(\v2\x1d.heimdallr.v1.ModmailSettingsR\bsettings\"\xcc\x01\n" + + "\x0fModmailSettings\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x124\n" + + "\x16report_threads_channel\x18\x02 \x01(\tR\x14reportThreadsChannel\x12>\n" + + "\x1breport_notification_channel\x18\x03 \x01(\tR\x19reportNotificationChannel\x12(\n" + + "\x10report_ping_role\x18\x04 \x01(\tR\x0ereportPingRole\"z\n" + + "\aChannel\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x03 \x01(\x05R\x04type\x12\x1a\n" + + "\bposition\x18\x04 \x01(\x05R\bposition\x12\x1b\n" + + "\tparent_id\x18\x05 \x01(\tR\bparentId\"v\n" + + "\x04Role\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + + "\x05color\x18\x03 \x01(\x05R\x05color\x12\x1a\n" + + "\bposition\x18\x04 \x01(\x05R\bposition\x12\x18\n" + + "\amanaged\x18\x05 \x01(\bR\amanaged\"0\n" + + "\x13ListChannelsRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"I\n" + + "\x14ListChannelsResponse\x121\n" + + "\bchannels\x18\x01 \x03(\v2\x15.heimdallr.v1.ChannelR\bchannels\"-\n" + + "\x10ListRolesRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\"=\n" + + "\x11ListRolesResponse\x12(\n" + + "\x05roles\x18\x01 \x03(\v2\x12.heimdallr.v1.RoleR\x05roles\"\x81\x01\n" + + "\x1cSendComponentsMessageRequest\x12\x19\n" + + "\bguild_id\x18\x01 \x01(\tR\aguildId\x12\x1d\n" + + "\n" + + "channel_id\x18\x02 \x01(\tR\tchannelId\x12'\n" + + "\x0fcomponents_json\x18\x03 \x01(\tR\x0ecomponentsJson\">\n" + + "\x1dSendComponentsMessageResponse\x12\x1d\n" + + "\n" + + "message_id\x18\x01 \x01(\tR\tmessageId\"Y\n" + + "\x13TemplatePlaceholder\x12 \n" + + "\vplaceholder\x18\x01 \x01(\tR\vplaceholder\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\" \n" + + "\x1eGetTemplatePlaceholdersRequest\"h\n" + + "\x1fGetTemplatePlaceholdersResponse\x12E\n" + + "\fplaceholders\x18\x01 \x03(\v2!.heimdallr.v1.TemplatePlaceholderR\fplaceholders2\x9b\x0e\n" + + "\x14GuildSettingsService\x12U\n" + + "\rGetModChannel\x12\".heimdallr.v1.GetModChannelRequest\x1a .heimdallr.v1.ModChannelSettings\x12[\n" + + "\x10UpdateModChannel\x12%.heimdallr.v1.UpdateModChannelRequest\x1a .heimdallr.v1.ModChannelSettings\x12e\n" + + "\x15GetInfractionSettings\x12*.heimdallr.v1.GetInfractionSettingsRequest\x1a .heimdallr.v1.InfractionSettings\x12k\n" + + "\x18UpdateInfractionSettings\x12-.heimdallr.v1.UpdateInfractionSettingsRequest\x1a .heimdallr.v1.InfractionSettings\x12_\n" + + "\x13GetGatekeepSettings\x12(.heimdallr.v1.GetGatekeepSettingsRequest\x1a\x1e.heimdallr.v1.GatekeepSettings\x12e\n" + + "\x16UpdateGatekeepSettings\x12+.heimdallr.v1.UpdateGatekeepSettingsRequest\x1a\x1e.heimdallr.v1.GatekeepSettings\x12b\n" + + "\x14GetJoinLeaveSettings\x12).heimdallr.v1.GetJoinLeaveSettingsRequest\x1a\x1f.heimdallr.v1.JoinLeaveSettings\x12h\n" + + "\x17UpdateJoinLeaveSettings\x12,.heimdallr.v1.UpdateJoinLeaveSettingsRequest\x1a\x1f.heimdallr.v1.JoinLeaveSettings\x12_\n" + + "\x13GetAntiSpamSettings\x12(.heimdallr.v1.GetAntiSpamSettingsRequest\x1a\x1e.heimdallr.v1.AntiSpamSettings\x12e\n" + + "\x16UpdateAntiSpamSettings\x12+.heimdallr.v1.UpdateAntiSpamSettingsRequest\x1a\x1e.heimdallr.v1.AntiSpamSettings\x12b\n" + + "\x14GetBanFooterSettings\x12).heimdallr.v1.GetBanFooterSettingsRequest\x1a\x1f.heimdallr.v1.BanFooterSettings\x12h\n" + + "\x17UpdateBanFooterSettings\x12,.heimdallr.v1.UpdateBanFooterSettingsRequest\x1a\x1f.heimdallr.v1.BanFooterSettings\x12\\\n" + + "\x12GetModmailSettings\x12'.heimdallr.v1.GetModmailSettingsRequest\x1a\x1d.heimdallr.v1.ModmailSettings\x12b\n" + + "\x15UpdateModmailSettings\x12*.heimdallr.v1.UpdateModmailSettingsRequest\x1a\x1d.heimdallr.v1.ModmailSettings\x12U\n" + + "\fListChannels\x12!.heimdallr.v1.ListChannelsRequest\x1a\".heimdallr.v1.ListChannelsResponse\x12L\n" + + "\tListRoles\x12\x1e.heimdallr.v1.ListRolesRequest\x1a\x1f.heimdallr.v1.ListRolesResponse\x12v\n" + + "\x17GetTemplatePlaceholders\x12,.heimdallr.v1.GetTemplatePlaceholdersRequest\x1a-.heimdallr.v1.GetTemplatePlaceholdersResponse\x12p\n" + + "\x15SendComponentsMessage\x12*.heimdallr.v1.SendComponentsMessageRequest\x1a+.heimdallr.v1.SendComponentsMessageResponseB\xb7\x01\n" + + "\x10com.heimdallr.v1B\x12GuildSettingsProtoP\x01Z>github.com/NLLCommunity/heimdallr/gen/heimdallr/v1;heimdallrv1\xa2\x02\x03HXX\xaa\x02\fHeimdallr.V1\xca\x02\fHeimdallr\\V1\xe2\x02\x18Heimdallr\\V1\\GPBMetadata\xea\x02\rHeimdallr::V1b\x06proto3" + +var ( + file_heimdallr_v1_guild_settings_proto_rawDescOnce sync.Once + file_heimdallr_v1_guild_settings_proto_rawDescData []byte +) + +func file_heimdallr_v1_guild_settings_proto_rawDescGZIP() []byte { + file_heimdallr_v1_guild_settings_proto_rawDescOnce.Do(func() { + file_heimdallr_v1_guild_settings_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_heimdallr_v1_guild_settings_proto_rawDesc), len(file_heimdallr_v1_guild_settings_proto_rawDesc))) + }) + return file_heimdallr_v1_guild_settings_proto_rawDescData +} + +var file_heimdallr_v1_guild_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_heimdallr_v1_guild_settings_proto_goTypes = []any{ + (*GetModChannelRequest)(nil), // 0: heimdallr.v1.GetModChannelRequest + (*UpdateModChannelRequest)(nil), // 1: heimdallr.v1.UpdateModChannelRequest + (*ModChannelSettings)(nil), // 2: heimdallr.v1.ModChannelSettings + (*GetInfractionSettingsRequest)(nil), // 3: heimdallr.v1.GetInfractionSettingsRequest + (*UpdateInfractionSettingsRequest)(nil), // 4: heimdallr.v1.UpdateInfractionSettingsRequest + (*InfractionSettings)(nil), // 5: heimdallr.v1.InfractionSettings + (*GetGatekeepSettingsRequest)(nil), // 6: heimdallr.v1.GetGatekeepSettingsRequest + (*UpdateGatekeepSettingsRequest)(nil), // 7: heimdallr.v1.UpdateGatekeepSettingsRequest + (*GatekeepSettings)(nil), // 8: heimdallr.v1.GatekeepSettings + (*GetJoinLeaveSettingsRequest)(nil), // 9: heimdallr.v1.GetJoinLeaveSettingsRequest + (*UpdateJoinLeaveSettingsRequest)(nil), // 10: heimdallr.v1.UpdateJoinLeaveSettingsRequest + (*JoinLeaveSettings)(nil), // 11: heimdallr.v1.JoinLeaveSettings + (*GetAntiSpamSettingsRequest)(nil), // 12: heimdallr.v1.GetAntiSpamSettingsRequest + (*UpdateAntiSpamSettingsRequest)(nil), // 13: heimdallr.v1.UpdateAntiSpamSettingsRequest + (*AntiSpamSettings)(nil), // 14: heimdallr.v1.AntiSpamSettings + (*GetBanFooterSettingsRequest)(nil), // 15: heimdallr.v1.GetBanFooterSettingsRequest + (*UpdateBanFooterSettingsRequest)(nil), // 16: heimdallr.v1.UpdateBanFooterSettingsRequest + (*BanFooterSettings)(nil), // 17: heimdallr.v1.BanFooterSettings + (*GetModmailSettingsRequest)(nil), // 18: heimdallr.v1.GetModmailSettingsRequest + (*UpdateModmailSettingsRequest)(nil), // 19: heimdallr.v1.UpdateModmailSettingsRequest + (*ModmailSettings)(nil), // 20: heimdallr.v1.ModmailSettings + (*Channel)(nil), // 21: heimdallr.v1.Channel + (*Role)(nil), // 22: heimdallr.v1.Role + (*ListChannelsRequest)(nil), // 23: heimdallr.v1.ListChannelsRequest + (*ListChannelsResponse)(nil), // 24: heimdallr.v1.ListChannelsResponse + (*ListRolesRequest)(nil), // 25: heimdallr.v1.ListRolesRequest + (*ListRolesResponse)(nil), // 26: heimdallr.v1.ListRolesResponse + (*SendComponentsMessageRequest)(nil), // 27: heimdallr.v1.SendComponentsMessageRequest + (*SendComponentsMessageResponse)(nil), // 28: heimdallr.v1.SendComponentsMessageResponse + (*TemplatePlaceholder)(nil), // 29: heimdallr.v1.TemplatePlaceholder + (*GetTemplatePlaceholdersRequest)(nil), // 30: heimdallr.v1.GetTemplatePlaceholdersRequest + (*GetTemplatePlaceholdersResponse)(nil), // 31: heimdallr.v1.GetTemplatePlaceholdersResponse +} +var file_heimdallr_v1_guild_settings_proto_depIdxs = []int32{ + 2, // 0: heimdallr.v1.UpdateModChannelRequest.settings:type_name -> heimdallr.v1.ModChannelSettings + 5, // 1: heimdallr.v1.UpdateInfractionSettingsRequest.settings:type_name -> heimdallr.v1.InfractionSettings + 8, // 2: heimdallr.v1.UpdateGatekeepSettingsRequest.settings:type_name -> heimdallr.v1.GatekeepSettings + 11, // 3: heimdallr.v1.UpdateJoinLeaveSettingsRequest.settings:type_name -> heimdallr.v1.JoinLeaveSettings + 14, // 4: heimdallr.v1.UpdateAntiSpamSettingsRequest.settings:type_name -> heimdallr.v1.AntiSpamSettings + 17, // 5: heimdallr.v1.UpdateBanFooterSettingsRequest.settings:type_name -> heimdallr.v1.BanFooterSettings + 20, // 6: heimdallr.v1.UpdateModmailSettingsRequest.settings:type_name -> heimdallr.v1.ModmailSettings + 21, // 7: heimdallr.v1.ListChannelsResponse.channels:type_name -> heimdallr.v1.Channel + 22, // 8: heimdallr.v1.ListRolesResponse.roles:type_name -> heimdallr.v1.Role + 29, // 9: heimdallr.v1.GetTemplatePlaceholdersResponse.placeholders:type_name -> heimdallr.v1.TemplatePlaceholder + 0, // 10: heimdallr.v1.GuildSettingsService.GetModChannel:input_type -> heimdallr.v1.GetModChannelRequest + 1, // 11: heimdallr.v1.GuildSettingsService.UpdateModChannel:input_type -> heimdallr.v1.UpdateModChannelRequest + 3, // 12: heimdallr.v1.GuildSettingsService.GetInfractionSettings:input_type -> heimdallr.v1.GetInfractionSettingsRequest + 4, // 13: heimdallr.v1.GuildSettingsService.UpdateInfractionSettings:input_type -> heimdallr.v1.UpdateInfractionSettingsRequest + 6, // 14: heimdallr.v1.GuildSettingsService.GetGatekeepSettings:input_type -> heimdallr.v1.GetGatekeepSettingsRequest + 7, // 15: heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings:input_type -> heimdallr.v1.UpdateGatekeepSettingsRequest + 9, // 16: heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings:input_type -> heimdallr.v1.GetJoinLeaveSettingsRequest + 10, // 17: heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings:input_type -> heimdallr.v1.UpdateJoinLeaveSettingsRequest + 12, // 18: heimdallr.v1.GuildSettingsService.GetAntiSpamSettings:input_type -> heimdallr.v1.GetAntiSpamSettingsRequest + 13, // 19: heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings:input_type -> heimdallr.v1.UpdateAntiSpamSettingsRequest + 15, // 20: heimdallr.v1.GuildSettingsService.GetBanFooterSettings:input_type -> heimdallr.v1.GetBanFooterSettingsRequest + 16, // 21: heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings:input_type -> heimdallr.v1.UpdateBanFooterSettingsRequest + 18, // 22: heimdallr.v1.GuildSettingsService.GetModmailSettings:input_type -> heimdallr.v1.GetModmailSettingsRequest + 19, // 23: heimdallr.v1.GuildSettingsService.UpdateModmailSettings:input_type -> heimdallr.v1.UpdateModmailSettingsRequest + 23, // 24: heimdallr.v1.GuildSettingsService.ListChannels:input_type -> heimdallr.v1.ListChannelsRequest + 25, // 25: heimdallr.v1.GuildSettingsService.ListRoles:input_type -> heimdallr.v1.ListRolesRequest + 30, // 26: heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders:input_type -> heimdallr.v1.GetTemplatePlaceholdersRequest + 27, // 27: heimdallr.v1.GuildSettingsService.SendComponentsMessage:input_type -> heimdallr.v1.SendComponentsMessageRequest + 2, // 28: heimdallr.v1.GuildSettingsService.GetModChannel:output_type -> heimdallr.v1.ModChannelSettings + 2, // 29: heimdallr.v1.GuildSettingsService.UpdateModChannel:output_type -> heimdallr.v1.ModChannelSettings + 5, // 30: heimdallr.v1.GuildSettingsService.GetInfractionSettings:output_type -> heimdallr.v1.InfractionSettings + 5, // 31: heimdallr.v1.GuildSettingsService.UpdateInfractionSettings:output_type -> heimdallr.v1.InfractionSettings + 8, // 32: heimdallr.v1.GuildSettingsService.GetGatekeepSettings:output_type -> heimdallr.v1.GatekeepSettings + 8, // 33: heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings:output_type -> heimdallr.v1.GatekeepSettings + 11, // 34: heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings:output_type -> heimdallr.v1.JoinLeaveSettings + 11, // 35: heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings:output_type -> heimdallr.v1.JoinLeaveSettings + 14, // 36: heimdallr.v1.GuildSettingsService.GetAntiSpamSettings:output_type -> heimdallr.v1.AntiSpamSettings + 14, // 37: heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings:output_type -> heimdallr.v1.AntiSpamSettings + 17, // 38: heimdallr.v1.GuildSettingsService.GetBanFooterSettings:output_type -> heimdallr.v1.BanFooterSettings + 17, // 39: heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings:output_type -> heimdallr.v1.BanFooterSettings + 20, // 40: heimdallr.v1.GuildSettingsService.GetModmailSettings:output_type -> heimdallr.v1.ModmailSettings + 20, // 41: heimdallr.v1.GuildSettingsService.UpdateModmailSettings:output_type -> heimdallr.v1.ModmailSettings + 24, // 42: heimdallr.v1.GuildSettingsService.ListChannels:output_type -> heimdallr.v1.ListChannelsResponse + 26, // 43: heimdallr.v1.GuildSettingsService.ListRoles:output_type -> heimdallr.v1.ListRolesResponse + 31, // 44: heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders:output_type -> heimdallr.v1.GetTemplatePlaceholdersResponse + 28, // 45: heimdallr.v1.GuildSettingsService.SendComponentsMessage:output_type -> heimdallr.v1.SendComponentsMessageResponse + 28, // [28:46] is the sub-list for method output_type + 10, // [10:28] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_heimdallr_v1_guild_settings_proto_init() } +func file_heimdallr_v1_guild_settings_proto_init() { + if File_heimdallr_v1_guild_settings_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_heimdallr_v1_guild_settings_proto_rawDesc), len(file_heimdallr_v1_guild_settings_proto_rawDesc)), + NumEnums: 0, + NumMessages: 32, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_heimdallr_v1_guild_settings_proto_goTypes, + DependencyIndexes: file_heimdallr_v1_guild_settings_proto_depIdxs, + MessageInfos: file_heimdallr_v1_guild_settings_proto_msgTypes, + }.Build() + File_heimdallr_v1_guild_settings_proto = out.File + file_heimdallr_v1_guild_settings_proto_goTypes = nil + file_heimdallr_v1_guild_settings_proto_depIdxs = nil +} diff --git a/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/auth.connect.go b/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/auth.connect.go new file mode 100644 index 0000000..abdb556 --- /dev/null +++ b/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/auth.connect.go @@ -0,0 +1,242 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: heimdallr/v1/auth.proto + +package heimdallrv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AuthServiceName is the fully-qualified name of the AuthService service. + AuthServiceName = "heimdallr.v1.AuthService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AuthServiceGetLoginURLProcedure is the fully-qualified name of the AuthService's GetLoginURL RPC. + AuthServiceGetLoginURLProcedure = "/heimdallr.v1.AuthService/GetLoginURL" + // AuthServiceExchangeCodeProcedure is the fully-qualified name of the AuthService's ExchangeCode + // RPC. + AuthServiceExchangeCodeProcedure = "/heimdallr.v1.AuthService/ExchangeCode" + // AuthServiceGetCurrentUserProcedure is the fully-qualified name of the AuthService's + // GetCurrentUser RPC. + AuthServiceGetCurrentUserProcedure = "/heimdallr.v1.AuthService/GetCurrentUser" + // AuthServiceListGuildsProcedure is the fully-qualified name of the AuthService's ListGuilds RPC. + AuthServiceListGuildsProcedure = "/heimdallr.v1.AuthService/ListGuilds" + // AuthServiceLogoutProcedure is the fully-qualified name of the AuthService's Logout RPC. + AuthServiceLogoutProcedure = "/heimdallr.v1.AuthService/Logout" +) + +// AuthServiceClient is a client for the heimdallr.v1.AuthService service. +type AuthServiceClient interface { + GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) + ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) + GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) + ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) + Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) +} + +// NewAuthServiceClient constructs a client for the heimdallr.v1.AuthService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAuthServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AuthServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + authServiceMethods := v1.File_heimdallr_v1_auth_proto.Services().ByName("AuthService").Methods() + return &authServiceClient{ + getLoginURL: connect.NewClient[v1.GetLoginURLRequest, v1.GetLoginURLResponse]( + httpClient, + baseURL+AuthServiceGetLoginURLProcedure, + connect.WithSchema(authServiceMethods.ByName("GetLoginURL")), + connect.WithClientOptions(opts...), + ), + exchangeCode: connect.NewClient[v1.ExchangeCodeRequest, v1.ExchangeCodeResponse]( + httpClient, + baseURL+AuthServiceExchangeCodeProcedure, + connect.WithSchema(authServiceMethods.ByName("ExchangeCode")), + connect.WithClientOptions(opts...), + ), + getCurrentUser: connect.NewClient[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse]( + httpClient, + baseURL+AuthServiceGetCurrentUserProcedure, + connect.WithSchema(authServiceMethods.ByName("GetCurrentUser")), + connect.WithClientOptions(opts...), + ), + listGuilds: connect.NewClient[v1.ListGuildsRequest, v1.ListGuildsResponse]( + httpClient, + baseURL+AuthServiceListGuildsProcedure, + connect.WithSchema(authServiceMethods.ByName("ListGuilds")), + connect.WithClientOptions(opts...), + ), + logout: connect.NewClient[v1.LogoutRequest, v1.LogoutResponse]( + httpClient, + baseURL+AuthServiceLogoutProcedure, + connect.WithSchema(authServiceMethods.ByName("Logout")), + connect.WithClientOptions(opts...), + ), + } +} + +// authServiceClient implements AuthServiceClient. +type authServiceClient struct { + getLoginURL *connect.Client[v1.GetLoginURLRequest, v1.GetLoginURLResponse] + exchangeCode *connect.Client[v1.ExchangeCodeRequest, v1.ExchangeCodeResponse] + getCurrentUser *connect.Client[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse] + listGuilds *connect.Client[v1.ListGuildsRequest, v1.ListGuildsResponse] + logout *connect.Client[v1.LogoutRequest, v1.LogoutResponse] +} + +// GetLoginURL calls heimdallr.v1.AuthService.GetLoginURL. +func (c *authServiceClient) GetLoginURL(ctx context.Context, req *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) { + response, err := c.getLoginURL.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ExchangeCode calls heimdallr.v1.AuthService.ExchangeCode. +func (c *authServiceClient) ExchangeCode(ctx context.Context, req *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) { + response, err := c.exchangeCode.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetCurrentUser calls heimdallr.v1.AuthService.GetCurrentUser. +func (c *authServiceClient) GetCurrentUser(ctx context.Context, req *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) { + response, err := c.getCurrentUser.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListGuilds calls heimdallr.v1.AuthService.ListGuilds. +func (c *authServiceClient) ListGuilds(ctx context.Context, req *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) { + response, err := c.listGuilds.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// Logout calls heimdallr.v1.AuthService.Logout. +func (c *authServiceClient) Logout(ctx context.Context, req *v1.LogoutRequest) (*v1.LogoutResponse, error) { + response, err := c.logout.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// AuthServiceHandler is an implementation of the heimdallr.v1.AuthService service. +type AuthServiceHandler interface { + GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) + ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) + GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) + ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) + Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) +} + +// NewAuthServiceHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAuthServiceHandler(svc AuthServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + authServiceMethods := v1.File_heimdallr_v1_auth_proto.Services().ByName("AuthService").Methods() + authServiceGetLoginURLHandler := connect.NewUnaryHandlerSimple( + AuthServiceGetLoginURLProcedure, + svc.GetLoginURL, + connect.WithSchema(authServiceMethods.ByName("GetLoginURL")), + connect.WithHandlerOptions(opts...), + ) + authServiceExchangeCodeHandler := connect.NewUnaryHandlerSimple( + AuthServiceExchangeCodeProcedure, + svc.ExchangeCode, + connect.WithSchema(authServiceMethods.ByName("ExchangeCode")), + connect.WithHandlerOptions(opts...), + ) + authServiceGetCurrentUserHandler := connect.NewUnaryHandlerSimple( + AuthServiceGetCurrentUserProcedure, + svc.GetCurrentUser, + connect.WithSchema(authServiceMethods.ByName("GetCurrentUser")), + connect.WithHandlerOptions(opts...), + ) + authServiceListGuildsHandler := connect.NewUnaryHandlerSimple( + AuthServiceListGuildsProcedure, + svc.ListGuilds, + connect.WithSchema(authServiceMethods.ByName("ListGuilds")), + connect.WithHandlerOptions(opts...), + ) + authServiceLogoutHandler := connect.NewUnaryHandlerSimple( + AuthServiceLogoutProcedure, + svc.Logout, + connect.WithSchema(authServiceMethods.ByName("Logout")), + connect.WithHandlerOptions(opts...), + ) + return "/heimdallr.v1.AuthService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AuthServiceGetLoginURLProcedure: + authServiceGetLoginURLHandler.ServeHTTP(w, r) + case AuthServiceExchangeCodeProcedure: + authServiceExchangeCodeHandler.ServeHTTP(w, r) + case AuthServiceGetCurrentUserProcedure: + authServiceGetCurrentUserHandler.ServeHTTP(w, r) + case AuthServiceListGuildsProcedure: + authServiceListGuildsHandler.ServeHTTP(w, r) + case AuthServiceLogoutProcedure: + authServiceLogoutHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAuthServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAuthServiceHandler struct{} + +func (UnimplementedAuthServiceHandler) GetLoginURL(context.Context, *v1.GetLoginURLRequest) (*v1.GetLoginURLResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.GetLoginURL is not implemented")) +} + +func (UnimplementedAuthServiceHandler) ExchangeCode(context.Context, *v1.ExchangeCodeRequest) (*v1.ExchangeCodeResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.ExchangeCode is not implemented")) +} + +func (UnimplementedAuthServiceHandler) GetCurrentUser(context.Context, *v1.GetCurrentUserRequest) (*v1.GetCurrentUserResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.GetCurrentUser is not implemented")) +} + +func (UnimplementedAuthServiceHandler) ListGuilds(context.Context, *v1.ListGuildsRequest) (*v1.ListGuildsResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.ListGuilds is not implemented")) +} + +func (UnimplementedAuthServiceHandler) Logout(context.Context, *v1.LogoutRequest) (*v1.LogoutResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.AuthService.Logout is not implemented")) +} diff --git a/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go b/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go new file mode 100644 index 0000000..e435a8b --- /dev/null +++ b/heimdallr/gen_/heimdallr/v1/heimdallrv1connect/guild_settings.connect.go @@ -0,0 +1,675 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: heimdallr/v1/guild_settings.proto + +package heimdallrv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // GuildSettingsServiceName is the fully-qualified name of the GuildSettingsService service. + GuildSettingsServiceName = "heimdallr.v1.GuildSettingsService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GuildSettingsServiceGetModChannelProcedure is the fully-qualified name of the + // GuildSettingsService's GetModChannel RPC. + GuildSettingsServiceGetModChannelProcedure = "/heimdallr.v1.GuildSettingsService/GetModChannel" + // GuildSettingsServiceUpdateModChannelProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateModChannel RPC. + GuildSettingsServiceUpdateModChannelProcedure = "/heimdallr.v1.GuildSettingsService/UpdateModChannel" + // GuildSettingsServiceGetInfractionSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetInfractionSettings RPC. + GuildSettingsServiceGetInfractionSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetInfractionSettings" + // GuildSettingsServiceUpdateInfractionSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateInfractionSettings RPC. + GuildSettingsServiceUpdateInfractionSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateInfractionSettings" + // GuildSettingsServiceGetGatekeepSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetGatekeepSettings RPC. + GuildSettingsServiceGetGatekeepSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetGatekeepSettings" + // GuildSettingsServiceUpdateGatekeepSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateGatekeepSettings RPC. + GuildSettingsServiceUpdateGatekeepSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateGatekeepSettings" + // GuildSettingsServiceGetJoinLeaveSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetJoinLeaveSettings RPC. + GuildSettingsServiceGetJoinLeaveSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetJoinLeaveSettings" + // GuildSettingsServiceUpdateJoinLeaveSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateJoinLeaveSettings RPC. + GuildSettingsServiceUpdateJoinLeaveSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateJoinLeaveSettings" + // GuildSettingsServiceGetAntiSpamSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetAntiSpamSettings RPC. + GuildSettingsServiceGetAntiSpamSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetAntiSpamSettings" + // GuildSettingsServiceUpdateAntiSpamSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateAntiSpamSettings RPC. + GuildSettingsServiceUpdateAntiSpamSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateAntiSpamSettings" + // GuildSettingsServiceGetBanFooterSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetBanFooterSettings RPC. + GuildSettingsServiceGetBanFooterSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetBanFooterSettings" + // GuildSettingsServiceUpdateBanFooterSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateBanFooterSettings RPC. + GuildSettingsServiceUpdateBanFooterSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateBanFooterSettings" + // GuildSettingsServiceGetModmailSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's GetModmailSettings RPC. + GuildSettingsServiceGetModmailSettingsProcedure = "/heimdallr.v1.GuildSettingsService/GetModmailSettings" + // GuildSettingsServiceUpdateModmailSettingsProcedure is the fully-qualified name of the + // GuildSettingsService's UpdateModmailSettings RPC. + GuildSettingsServiceUpdateModmailSettingsProcedure = "/heimdallr.v1.GuildSettingsService/UpdateModmailSettings" + // GuildSettingsServiceListChannelsProcedure is the fully-qualified name of the + // GuildSettingsService's ListChannels RPC. + GuildSettingsServiceListChannelsProcedure = "/heimdallr.v1.GuildSettingsService/ListChannels" + // GuildSettingsServiceListRolesProcedure is the fully-qualified name of the GuildSettingsService's + // ListRoles RPC. + GuildSettingsServiceListRolesProcedure = "/heimdallr.v1.GuildSettingsService/ListRoles" + // GuildSettingsServiceGetTemplatePlaceholdersProcedure is the fully-qualified name of the + // GuildSettingsService's GetTemplatePlaceholders RPC. + GuildSettingsServiceGetTemplatePlaceholdersProcedure = "/heimdallr.v1.GuildSettingsService/GetTemplatePlaceholders" + // GuildSettingsServiceSendComponentsMessageProcedure is the fully-qualified name of the + // GuildSettingsService's SendComponentsMessage RPC. + GuildSettingsServiceSendComponentsMessageProcedure = "/heimdallr.v1.GuildSettingsService/SendComponentsMessage" +) + +// GuildSettingsServiceClient is a client for the heimdallr.v1.GuildSettingsService service. +type GuildSettingsServiceClient interface { + GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) + UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) + GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) + UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) + GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) + UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) + ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) + ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) + GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) + SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) +} + +// NewGuildSettingsServiceClient constructs a client for the heimdallr.v1.GuildSettingsService +// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for +// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply +// the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewGuildSettingsServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GuildSettingsServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + guildSettingsServiceMethods := v1.File_heimdallr_v1_guild_settings_proto.Services().ByName("GuildSettingsService").Methods() + return &guildSettingsServiceClient{ + getModChannel: connect.NewClient[v1.GetModChannelRequest, v1.ModChannelSettings]( + httpClient, + baseURL+GuildSettingsServiceGetModChannelProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModChannel")), + connect.WithClientOptions(opts...), + ), + updateModChannel: connect.NewClient[v1.UpdateModChannelRequest, v1.ModChannelSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateModChannelProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModChannel")), + connect.WithClientOptions(opts...), + ), + getInfractionSettings: connect.NewClient[v1.GetInfractionSettingsRequest, v1.InfractionSettings]( + httpClient, + baseURL+GuildSettingsServiceGetInfractionSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetInfractionSettings")), + connect.WithClientOptions(opts...), + ), + updateInfractionSettings: connect.NewClient[v1.UpdateInfractionSettingsRequest, v1.InfractionSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateInfractionSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateInfractionSettings")), + connect.WithClientOptions(opts...), + ), + getGatekeepSettings: connect.NewClient[v1.GetGatekeepSettingsRequest, v1.GatekeepSettings]( + httpClient, + baseURL+GuildSettingsServiceGetGatekeepSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetGatekeepSettings")), + connect.WithClientOptions(opts...), + ), + updateGatekeepSettings: connect.NewClient[v1.UpdateGatekeepSettingsRequest, v1.GatekeepSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateGatekeepSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateGatekeepSettings")), + connect.WithClientOptions(opts...), + ), + getJoinLeaveSettings: connect.NewClient[v1.GetJoinLeaveSettingsRequest, v1.JoinLeaveSettings]( + httpClient, + baseURL+GuildSettingsServiceGetJoinLeaveSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetJoinLeaveSettings")), + connect.WithClientOptions(opts...), + ), + updateJoinLeaveSettings: connect.NewClient[v1.UpdateJoinLeaveSettingsRequest, v1.JoinLeaveSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateJoinLeaveSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateJoinLeaveSettings")), + connect.WithClientOptions(opts...), + ), + getAntiSpamSettings: connect.NewClient[v1.GetAntiSpamSettingsRequest, v1.AntiSpamSettings]( + httpClient, + baseURL+GuildSettingsServiceGetAntiSpamSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetAntiSpamSettings")), + connect.WithClientOptions(opts...), + ), + updateAntiSpamSettings: connect.NewClient[v1.UpdateAntiSpamSettingsRequest, v1.AntiSpamSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateAntiSpamSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateAntiSpamSettings")), + connect.WithClientOptions(opts...), + ), + getBanFooterSettings: connect.NewClient[v1.GetBanFooterSettingsRequest, v1.BanFooterSettings]( + httpClient, + baseURL+GuildSettingsServiceGetBanFooterSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetBanFooterSettings")), + connect.WithClientOptions(opts...), + ), + updateBanFooterSettings: connect.NewClient[v1.UpdateBanFooterSettingsRequest, v1.BanFooterSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateBanFooterSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateBanFooterSettings")), + connect.WithClientOptions(opts...), + ), + getModmailSettings: connect.NewClient[v1.GetModmailSettingsRequest, v1.ModmailSettings]( + httpClient, + baseURL+GuildSettingsServiceGetModmailSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModmailSettings")), + connect.WithClientOptions(opts...), + ), + updateModmailSettings: connect.NewClient[v1.UpdateModmailSettingsRequest, v1.ModmailSettings]( + httpClient, + baseURL+GuildSettingsServiceUpdateModmailSettingsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModmailSettings")), + connect.WithClientOptions(opts...), + ), + listChannels: connect.NewClient[v1.ListChannelsRequest, v1.ListChannelsResponse]( + httpClient, + baseURL+GuildSettingsServiceListChannelsProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListChannels")), + connect.WithClientOptions(opts...), + ), + listRoles: connect.NewClient[v1.ListRolesRequest, v1.ListRolesResponse]( + httpClient, + baseURL+GuildSettingsServiceListRolesProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListRoles")), + connect.WithClientOptions(opts...), + ), + getTemplatePlaceholders: connect.NewClient[v1.GetTemplatePlaceholdersRequest, v1.GetTemplatePlaceholdersResponse]( + httpClient, + baseURL+GuildSettingsServiceGetTemplatePlaceholdersProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetTemplatePlaceholders")), + connect.WithClientOptions(opts...), + ), + sendComponentsMessage: connect.NewClient[v1.SendComponentsMessageRequest, v1.SendComponentsMessageResponse]( + httpClient, + baseURL+GuildSettingsServiceSendComponentsMessageProcedure, + connect.WithSchema(guildSettingsServiceMethods.ByName("SendComponentsMessage")), + connect.WithClientOptions(opts...), + ), + } +} + +// guildSettingsServiceClient implements GuildSettingsServiceClient. +type guildSettingsServiceClient struct { + getModChannel *connect.Client[v1.GetModChannelRequest, v1.ModChannelSettings] + updateModChannel *connect.Client[v1.UpdateModChannelRequest, v1.ModChannelSettings] + getInfractionSettings *connect.Client[v1.GetInfractionSettingsRequest, v1.InfractionSettings] + updateInfractionSettings *connect.Client[v1.UpdateInfractionSettingsRequest, v1.InfractionSettings] + getGatekeepSettings *connect.Client[v1.GetGatekeepSettingsRequest, v1.GatekeepSettings] + updateGatekeepSettings *connect.Client[v1.UpdateGatekeepSettingsRequest, v1.GatekeepSettings] + getJoinLeaveSettings *connect.Client[v1.GetJoinLeaveSettingsRequest, v1.JoinLeaveSettings] + updateJoinLeaveSettings *connect.Client[v1.UpdateJoinLeaveSettingsRequest, v1.JoinLeaveSettings] + getAntiSpamSettings *connect.Client[v1.GetAntiSpamSettingsRequest, v1.AntiSpamSettings] + updateAntiSpamSettings *connect.Client[v1.UpdateAntiSpamSettingsRequest, v1.AntiSpamSettings] + getBanFooterSettings *connect.Client[v1.GetBanFooterSettingsRequest, v1.BanFooterSettings] + updateBanFooterSettings *connect.Client[v1.UpdateBanFooterSettingsRequest, v1.BanFooterSettings] + getModmailSettings *connect.Client[v1.GetModmailSettingsRequest, v1.ModmailSettings] + updateModmailSettings *connect.Client[v1.UpdateModmailSettingsRequest, v1.ModmailSettings] + listChannels *connect.Client[v1.ListChannelsRequest, v1.ListChannelsResponse] + listRoles *connect.Client[v1.ListRolesRequest, v1.ListRolesResponse] + getTemplatePlaceholders *connect.Client[v1.GetTemplatePlaceholdersRequest, v1.GetTemplatePlaceholdersResponse] + sendComponentsMessage *connect.Client[v1.SendComponentsMessageRequest, v1.SendComponentsMessageResponse] +} + +// GetModChannel calls heimdallr.v1.GuildSettingsService.GetModChannel. +func (c *guildSettingsServiceClient) GetModChannel(ctx context.Context, req *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) { + response, err := c.getModChannel.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateModChannel calls heimdallr.v1.GuildSettingsService.UpdateModChannel. +func (c *guildSettingsServiceClient) UpdateModChannel(ctx context.Context, req *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) { + response, err := c.updateModChannel.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetInfractionSettings calls heimdallr.v1.GuildSettingsService.GetInfractionSettings. +func (c *guildSettingsServiceClient) GetInfractionSettings(ctx context.Context, req *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) { + response, err := c.getInfractionSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateInfractionSettings calls heimdallr.v1.GuildSettingsService.UpdateInfractionSettings. +func (c *guildSettingsServiceClient) UpdateInfractionSettings(ctx context.Context, req *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) { + response, err := c.updateInfractionSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetGatekeepSettings calls heimdallr.v1.GuildSettingsService.GetGatekeepSettings. +func (c *guildSettingsServiceClient) GetGatekeepSettings(ctx context.Context, req *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + response, err := c.getGatekeepSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateGatekeepSettings calls heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings. +func (c *guildSettingsServiceClient) UpdateGatekeepSettings(ctx context.Context, req *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + response, err := c.updateGatekeepSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetJoinLeaveSettings calls heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings. +func (c *guildSettingsServiceClient) GetJoinLeaveSettings(ctx context.Context, req *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + response, err := c.getJoinLeaveSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateJoinLeaveSettings calls heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings. +func (c *guildSettingsServiceClient) UpdateJoinLeaveSettings(ctx context.Context, req *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + response, err := c.updateJoinLeaveSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetAntiSpamSettings calls heimdallr.v1.GuildSettingsService.GetAntiSpamSettings. +func (c *guildSettingsServiceClient) GetAntiSpamSettings(ctx context.Context, req *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + response, err := c.getAntiSpamSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateAntiSpamSettings calls heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings. +func (c *guildSettingsServiceClient) UpdateAntiSpamSettings(ctx context.Context, req *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + response, err := c.updateAntiSpamSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetBanFooterSettings calls heimdallr.v1.GuildSettingsService.GetBanFooterSettings. +func (c *guildSettingsServiceClient) GetBanFooterSettings(ctx context.Context, req *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + response, err := c.getBanFooterSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateBanFooterSettings calls heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings. +func (c *guildSettingsServiceClient) UpdateBanFooterSettings(ctx context.Context, req *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + response, err := c.updateBanFooterSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetModmailSettings calls heimdallr.v1.GuildSettingsService.GetModmailSettings. +func (c *guildSettingsServiceClient) GetModmailSettings(ctx context.Context, req *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) { + response, err := c.getModmailSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// UpdateModmailSettings calls heimdallr.v1.GuildSettingsService.UpdateModmailSettings. +func (c *guildSettingsServiceClient) UpdateModmailSettings(ctx context.Context, req *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) { + response, err := c.updateModmailSettings.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListChannels calls heimdallr.v1.GuildSettingsService.ListChannels. +func (c *guildSettingsServiceClient) ListChannels(ctx context.Context, req *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) { + response, err := c.listChannels.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// ListRoles calls heimdallr.v1.GuildSettingsService.ListRoles. +func (c *guildSettingsServiceClient) ListRoles(ctx context.Context, req *v1.ListRolesRequest) (*v1.ListRolesResponse, error) { + response, err := c.listRoles.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GetTemplatePlaceholders calls heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders. +func (c *guildSettingsServiceClient) GetTemplatePlaceholders(ctx context.Context, req *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) { + response, err := c.getTemplatePlaceholders.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// SendComponentsMessage calls heimdallr.v1.GuildSettingsService.SendComponentsMessage. +func (c *guildSettingsServiceClient) SendComponentsMessage(ctx context.Context, req *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) { + response, err := c.sendComponentsMessage.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + +// GuildSettingsServiceHandler is an implementation of the heimdallr.v1.GuildSettingsService +// service. +type GuildSettingsServiceHandler interface { + GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) + UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) + GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) + UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) + GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) + GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) + GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) + GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) + GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) + UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) + ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) + ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) + GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) + SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) +} + +// NewGuildSettingsServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewGuildSettingsServiceHandler(svc GuildSettingsServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + guildSettingsServiceMethods := v1.File_heimdallr_v1_guild_settings_proto.Services().ByName("GuildSettingsService").Methods() + guildSettingsServiceGetModChannelHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetModChannelProcedure, + svc.GetModChannel, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModChannel")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateModChannelHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateModChannelProcedure, + svc.UpdateModChannel, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModChannel")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetInfractionSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetInfractionSettingsProcedure, + svc.GetInfractionSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetInfractionSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateInfractionSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateInfractionSettingsProcedure, + svc.UpdateInfractionSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateInfractionSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetGatekeepSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetGatekeepSettingsProcedure, + svc.GetGatekeepSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetGatekeepSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateGatekeepSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateGatekeepSettingsProcedure, + svc.UpdateGatekeepSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateGatekeepSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetJoinLeaveSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetJoinLeaveSettingsProcedure, + svc.GetJoinLeaveSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetJoinLeaveSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateJoinLeaveSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateJoinLeaveSettingsProcedure, + svc.UpdateJoinLeaveSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateJoinLeaveSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetAntiSpamSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetAntiSpamSettingsProcedure, + svc.GetAntiSpamSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetAntiSpamSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateAntiSpamSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateAntiSpamSettingsProcedure, + svc.UpdateAntiSpamSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateAntiSpamSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetBanFooterSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetBanFooterSettingsProcedure, + svc.GetBanFooterSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetBanFooterSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateBanFooterSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateBanFooterSettingsProcedure, + svc.UpdateBanFooterSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateBanFooterSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetModmailSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetModmailSettingsProcedure, + svc.GetModmailSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetModmailSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceUpdateModmailSettingsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceUpdateModmailSettingsProcedure, + svc.UpdateModmailSettings, + connect.WithSchema(guildSettingsServiceMethods.ByName("UpdateModmailSettings")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceListChannelsHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceListChannelsProcedure, + svc.ListChannels, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListChannels")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceListRolesHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceListRolesProcedure, + svc.ListRoles, + connect.WithSchema(guildSettingsServiceMethods.ByName("ListRoles")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceGetTemplatePlaceholdersHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceGetTemplatePlaceholdersProcedure, + svc.GetTemplatePlaceholders, + connect.WithSchema(guildSettingsServiceMethods.ByName("GetTemplatePlaceholders")), + connect.WithHandlerOptions(opts...), + ) + guildSettingsServiceSendComponentsMessageHandler := connect.NewUnaryHandlerSimple( + GuildSettingsServiceSendComponentsMessageProcedure, + svc.SendComponentsMessage, + connect.WithSchema(guildSettingsServiceMethods.ByName("SendComponentsMessage")), + connect.WithHandlerOptions(opts...), + ) + return "/heimdallr.v1.GuildSettingsService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case GuildSettingsServiceGetModChannelProcedure: + guildSettingsServiceGetModChannelHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateModChannelProcedure: + guildSettingsServiceUpdateModChannelHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetInfractionSettingsProcedure: + guildSettingsServiceGetInfractionSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateInfractionSettingsProcedure: + guildSettingsServiceUpdateInfractionSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetGatekeepSettingsProcedure: + guildSettingsServiceGetGatekeepSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateGatekeepSettingsProcedure: + guildSettingsServiceUpdateGatekeepSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetJoinLeaveSettingsProcedure: + guildSettingsServiceGetJoinLeaveSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateJoinLeaveSettingsProcedure: + guildSettingsServiceUpdateJoinLeaveSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetAntiSpamSettingsProcedure: + guildSettingsServiceGetAntiSpamSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateAntiSpamSettingsProcedure: + guildSettingsServiceUpdateAntiSpamSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetBanFooterSettingsProcedure: + guildSettingsServiceGetBanFooterSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateBanFooterSettingsProcedure: + guildSettingsServiceUpdateBanFooterSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetModmailSettingsProcedure: + guildSettingsServiceGetModmailSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceUpdateModmailSettingsProcedure: + guildSettingsServiceUpdateModmailSettingsHandler.ServeHTTP(w, r) + case GuildSettingsServiceListChannelsProcedure: + guildSettingsServiceListChannelsHandler.ServeHTTP(w, r) + case GuildSettingsServiceListRolesProcedure: + guildSettingsServiceListRolesHandler.ServeHTTP(w, r) + case GuildSettingsServiceGetTemplatePlaceholdersProcedure: + guildSettingsServiceGetTemplatePlaceholdersHandler.ServeHTTP(w, r) + case GuildSettingsServiceSendComponentsMessageProcedure: + guildSettingsServiceSendComponentsMessageHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedGuildSettingsServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedGuildSettingsServiceHandler struct{} + +func (UnimplementedGuildSettingsServiceHandler) GetModChannel(context.Context, *v1.GetModChannelRequest) (*v1.ModChannelSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetModChannel is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateModChannel(context.Context, *v1.UpdateModChannelRequest) (*v1.ModChannelSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateModChannel is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetInfractionSettings(context.Context, *v1.GetInfractionSettingsRequest) (*v1.InfractionSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetInfractionSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateInfractionSettings(context.Context, *v1.UpdateInfractionSettingsRequest) (*v1.InfractionSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateInfractionSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetGatekeepSettings(context.Context, *v1.GetGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetGatekeepSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateGatekeepSettings(context.Context, *v1.UpdateGatekeepSettingsRequest) (*v1.GatekeepSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetJoinLeaveSettings(context.Context, *v1.GetJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateJoinLeaveSettings(context.Context, *v1.UpdateJoinLeaveSettingsRequest) (*v1.JoinLeaveSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetAntiSpamSettings(context.Context, *v1.GetAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetAntiSpamSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateAntiSpamSettings(context.Context, *v1.UpdateAntiSpamSettingsRequest) (*v1.AntiSpamSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetBanFooterSettings(context.Context, *v1.GetBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetBanFooterSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateBanFooterSettings(context.Context, *v1.UpdateBanFooterSettingsRequest) (*v1.BanFooterSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetModmailSettings(context.Context, *v1.GetModmailSettingsRequest) (*v1.ModmailSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetModmailSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) UpdateModmailSettings(context.Context, *v1.UpdateModmailSettingsRequest) (*v1.ModmailSettings, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.UpdateModmailSettings is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) ListChannels(context.Context, *v1.ListChannelsRequest) (*v1.ListChannelsResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.ListChannels is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) ListRoles(context.Context, *v1.ListRolesRequest) (*v1.ListRolesResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.ListRoles is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) GetTemplatePlaceholders(context.Context, *v1.GetTemplatePlaceholdersRequest) (*v1.GetTemplatePlaceholdersResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders is not implemented")) +} + +func (UnimplementedGuildSettingsServiceHandler) SendComponentsMessage(context.Context, *v1.SendComponentsMessageRequest) (*v1.SendComponentsMessageResponse, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("heimdallr.v1.GuildSettingsService.SendComponentsMessage is not implemented")) +} diff --git a/heimdallr/generate.go b/heimdallr/generate.go new file mode 100644 index 0000000..ebed5e9 --- /dev/null +++ b/heimdallr/generate.go @@ -0,0 +1,5 @@ +package main + +//go:generate go tool buf dep update +//go:generate go tool buf generate +//go:generate mkdir -p ./rpcserver/frontend diff --git a/heimdallr/go.mod b/heimdallr/go.mod new file mode 100644 index 0000000..bebc06e --- /dev/null +++ b/heimdallr/go.mod @@ -0,0 +1,153 @@ +module github.com/NLLCommunity/heimdallr + +go 1.26.0 + +require ( + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 + connectrpc.com/connect v1.19.1 + connectrpc.com/grpcreflect v1.3.0 + connectrpc.com/validate v0.6.0 + github.com/agnivade/levenshtein v1.2.1 + github.com/cbroglie/mustache v1.4.0 + github.com/disgoorg/disgo v0.19.2 + github.com/disgoorg/omit v1.0.0 + github.com/disgoorg/snowflake/v2 v2.0.3 + github.com/glebarez/sqlite v1.11.0 + github.com/google/uuid v1.6.0 + github.com/jellydator/ttlcache/v3 v3.4.0 + github.com/rs/cors v1.11.1 + github.com/spf13/viper v1.21.0 + github.com/sqids/sqids-go v0.4.1 + github.com/stretchr/testify v1.11.1 + golang.org/x/time v0.14.0 + google.golang.org/protobuf v1.36.11 + gorm.io/gorm v1.31.1 +) + +require golang.org/x/sync v0.19.0 // indirect + +require ( + buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.11-20250718181942-e35f9b667443.1 // indirect + buf.build/gen/go/bufbuild/protodescriptor/protocolbuffers/go v1.36.11-20250109164928-1da0de137947.1 // indirect + buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.1-20260126144947-819582968857.2 // indirect + buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.11-20260126144947-819582968857.1 // indirect + buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.11-20241007202033-cf42259fcbfc.1 // indirect + buf.build/go/app v0.2.0 // indirect + buf.build/go/bufplugin v0.9.0 // indirect + buf.build/go/bufprivateusage v0.1.0 // indirect + buf.build/go/interrupt v1.1.0 // indirect + buf.build/go/protovalidate v1.1.0 // indirect + buf.build/go/protoyaml v0.6.0 // indirect + buf.build/go/spdx v0.2.0 // indirect + buf.build/go/standard v0.1.0 // indirect + cel.dev/expr v0.25.1 // indirect + connectrpc.com/otelconnect v0.9.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect + github.com/bufbuild/buf v1.65.0 // indirect + github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e // indirect + github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cli/browser v1.3.0 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076 // indirect + github.com/disgoorg/json/v2 v2.0.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/cli v29.2.0+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v28.5.2+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.5 // indirect + github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/glebarez/go-sqlite v1.22.0 // indirect + github.com/go-chi/chi/v5 v5.2.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect + github.com/gofrs/flock v0.13.0 // indirect + github.com/google/cel-go v0.27.0 // indirect + github.com/google/go-containerregistry v0.20.7 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jdx/go-netrc v1.0.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/term v0.5.2 // indirect + github.com/morikuni/aec v1.1.0 // indirect + github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect + github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect + github.com/segmentio/asm v1.2.1 // indirect + github.com/segmentio/encoding v0.5.3 // indirect + github.com/sirupsen/logrus v1.9.4 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/stretchr/objx v0.5.3 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/tetratelabs/wazero v1.11.0 // indirect + github.com/tidwall/btree v1.8.1 // indirect + github.com/vbatts/tar-split v0.12.2 // indirect + go.lsp.dev/jsonrpc2 v0.10.0 // indirect + go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 // indirect + go.lsp.dev/protocol v0.12.0 // indirect + go.lsp.dev/uri v0.3.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/grpc v1.78.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + modernc.org/libc v1.67.7 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect + modernc.org/sqlite v1.45.0 // indirect + mvdan.cc/xurls/v2 v2.6.0 // indirect + pluginrpc.com/pluginrpc v0.5.0 // indirect +) + +tool ( + connectrpc.com/connect/cmd/protoc-gen-connect-go + github.com/bufbuild/buf/cmd/buf + google.golang.org/protobuf/cmd/protoc-gen-go +) diff --git a/heimdallr/go.sum b/heimdallr/go.sum new file mode 100644 index 0000000..451b87b --- /dev/null +++ b/heimdallr/go.sum @@ -0,0 +1,360 @@ +buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.11-20250718181942-e35f9b667443.1 h1:zQ9C3e6FtwSZUFuKAQfpIKGFk5ZuRoGt5g35Bix55sI= +buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.11-20250718181942-e35f9b667443.1/go.mod h1:1Znr6gmYBhbxWUPRrrVnSLXQsz8bvFVw1HHJq2bI3VQ= +buf.build/gen/go/bufbuild/protodescriptor/protocolbuffers/go v1.36.11-20250109164928-1da0de137947.1 h1:HwzzCRS4ZrEm1++rzSDxHnO0DOjiT1b8I/24e8a4exY= +buf.build/gen/go/bufbuild/protodescriptor/protocolbuffers/go v1.36.11-20250109164928-1da0de137947.1/go.mod h1:8PRKXhgNes29Tjrnv8KdZzg3I1QceOkzibW1QK7EXv0= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 h1:j9yeqTWEFrtimt8Nng2MIeRrpoCvQzM9/g25XTvqUGg= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= +buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.1-20260126144947-819582968857.2 h1:XPrWCd9ydEo5Ofv1aNJVJaxndMXLQjRO9vVzsJG3jL8= +buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.1-20260126144947-819582968857.2/go.mod h1:mpsjeEaxOYPIJV2cz4IagLghZufRvx+NPVtInjEeoQ8= +buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.11-20260126144947-819582968857.1 h1:Yreby6Ypa58wdQUEm9Fnc5g8n/jP487Dq3aK5yBYwfk= +buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.11-20260126144947-819582968857.1/go.mod h1:1JJi9jvOqRxSMa+JxiZSm57doB+db/1WYCIa2lHfc40= +buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.11-20241007202033-cf42259fcbfc.1 h1:iGPvEJltOXUMANWf0zajcRcbiOXLD90ZwPUFvbcuv6Q= +buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.11-20241007202033-cf42259fcbfc.1/go.mod h1:nWVKKRA29zdt4uvkjka3i/y4mkrswyWwiu0TbdX0zts= +buf.build/go/app v0.2.0 h1:NYaH13A+RzPb7M5vO8uZYZ2maBZI5+MS9A9tQm66fy8= +buf.build/go/app v0.2.0/go.mod h1:0XVOYemubVbxNXVY0DnsVgWeGkcbbAvjDa1fmhBC+Wo= +buf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo= +buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY= +buf.build/go/bufprivateusage v0.1.0 h1:SzCoCcmzS3zyXHEXHeSQhGI7OTkgtljoknLzsUz9Gg4= +buf.build/go/bufprivateusage v0.1.0/go.mod h1:GlCCJ3VVF7EqqU0CoRmo1FzAwwaKymEWSr+ty69xU5w= +buf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE= +buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM= +buf.build/go/protovalidate v1.1.0 h1:pQqEQRpOo4SqS60qkvmhLTTQU9JwzEvdyiqAtXa5SeY= +buf.build/go/protovalidate v1.1.0/go.mod h1:bGZcPiAQDC3ErCHK3t74jSoJDFOs2JH3d7LWuTEIdss= +buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w= +buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q= +buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw= +buf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8= +buf.build/go/standard v0.1.0 h1:g98T9IyvAl0vS3Pq8iVk6Cvj2ZiFvoUJRtfyGa0120U= +buf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14= +connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w= +connectrpc.com/grpcreflect v1.3.0 h1:Y4V+ACf8/vOb1XOc251Qun7jMB75gCUNw6llvB9csXc= +connectrpc.com/grpcreflect v1.3.0/go.mod h1:nfloOtCS8VUQOQ1+GTdFzVg2CJo4ZGaat8JIovCtDYs= +connectrpc.com/otelconnect v0.9.0 h1:NggB3pzRC3pukQWaYbRHJulxuXvmCKCKkQ9hbrHAWoA= +connectrpc.com/otelconnect v0.9.0/go.mod h1:AEkVLjCPXra+ObGFCOClcJkNjS7zPaQSqvO0lCyjfZc= +connectrpc.com/validate v0.6.0 h1:DcrgDKt2ZScrUs/d/mh9itD2yeEa0UbBBa+i0mwzx+4= +connectrpc.com/validate v0.6.0/go.mod h1:ihrpI+8gVbLH1fvVWJL1I3j0CfWnF8P/90LsmluRiZs= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= +github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs= +github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= +github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= +github.com/bufbuild/buf v1.65.0 h1:f2BzeCY9rRh9P5KD340ZoPAaFLTkssoUTHx7lpqozgg= +github.com/bufbuild/buf v1.65.0/go.mod h1:7SAs2YqGpPXHqBBXBeYQbCzY0OQq4Jbg6XCqirEiYvQ= +github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e h1:emH16Bf1w4C0cJ3ge4QtBAl4sIYJe23EfpWH0SpA9co= +github.com/bufbuild/protocompile v0.14.2-0.20260130195850-5c64bed4577e/go.mod h1:cxhE8h+14t0Yxq2H9MV/UggzQ1L0gh0t2tJobITWsBE= +github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU= +github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ= +github.com/cbroglie/mustache v1.4.0 h1:Azg0dVhxTml5me+7PsZ7WPrQq1Gkf3WApcHMjMprYoU= +github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9DtDsHo9iM= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= +github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw= +github.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= +github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/disgoorg/disgo v0.19.2 h1:9FTTnYZ5RnLX6oybPr18d9+ht2KxIMkG/+HY0ADqTbM= +github.com/disgoorg/disgo v0.19.2/go.mod h1:rLCcf3vnlyfOTGw8ksVmq5UE5CMzBA0eeA9oeZ+N0x4= +github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076 h1:GN4w6H8zlH/kFRFnzjk+4Kg9KEUJ+jY0e4MZaGlFKh8= +github.com/disgoorg/godave v0.0.0-20260211223842-18cd5c306076/go.mod h1:OreAC3hpabr39bMVA+jwOVDq1EUPXH5A0XUBiZaDI1Y= +github.com/disgoorg/json/v2 v2.0.0 h1:U16yy/ARK7/aEpzjjqK1b/KaqqGHozUdeVw/DViEzQI= +github.com/disgoorg/json/v2 v2.0.0/go.mod h1:jZTBC0nIE1WeetSEI3/Dka8g+qglb4FPVmp5I5HpEfI= +github.com/disgoorg/omit v1.0.0 h1:y0LkVUOyUHT8ZlnhIAeOZEA22UYykeysK8bLJ0SfT78= +github.com/disgoorg/omit v1.0.0/go.mod h1:RTmSARkf6PWT/UckwI0bV8XgWkWQoPppaT01rYKLcFQ= +github.com/disgoorg/snowflake/v2 v2.0.3 h1:3B+PpFjr7j4ad7oeJu4RlQ+nYOTadsKapJIzgvSI2Ro= +github.com/disgoorg/snowflake/v2 v2.0.3/go.mod h1:W6r7NUA7DwfZLwr00km6G4UnZ0zcoLBRufhkFWgAc4c= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM= +github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= +github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= +github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= +github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= +github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= +github.com/go-chi/chi/v5 v5.2.4 h1:WtFKPHwlywe8Srng8j2BhOD9312j9cGUxG1SP4V2cR4= +github.com/go-chi/chi/v5 v5.2.4/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= +github.com/google/cel-go v0.27.0 h1:e7ih85+4qVrBuqQWTW4FKSqZYokVuc3HnhH5keboFTo= +github.com/google/cel-go v0.27.0/go.mod h1:tTJ11FWqnhw5KKpnWpvW9CJC3Y9GK4EIS0WXnBbebzw= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I= +github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8 h1:NpbJl/eVbvrGE0MJ6X16X9SAifesl6Fwxg/YmCvubRI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8/go.mod h1:mi7YA+gCzVem12exXy46ZespvGtX/lZmD/RLnQhVW7U= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jdx/go-netrc v1.0.0 h1:QbLMLyCZGj0NA8glAhxUpf1zDg6cxnWgMBbjq40W0gQ= +github.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569zF3v8= +github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= +github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= +github.com/jhump/protoreflect/v2 v2.0.0-beta.2 h1:qZU+rEZUOYTz1Bnhi3xbwn+VxdXkLVeEpAeZzVXLY88= +github.com/jhump/protoreflect/v2 v2.0.0-beta.2/go.mod h1:4tnOYkB/mq7QTyS3YKtVtNrJv4Psqout8HA1U+hZtgM= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= +github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/morikuni/aec v1.1.0 h1:vBBl0pUnvi/Je71dsRrhMBtreIqNMYErSAbEeb8jrXQ= +github.com/morikuni/aec v1.1.0/go.mod h1:xDRgiq/iw5l+zkao76YTKzKttOp2cwPEne25HDkJnBw= +github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= +github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14= +github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/protocolbuffers/protoscope v0.0.0-20221109213918-8e7a6aafa2c9 h1:arwj11zP0yJIxIRiDn22E0H8PxfF7TsTrc2wIPFIsf4= +github.com/protocolbuffers/protoscope v0.0.0-20221109213918-8e7a6aafa2c9/go.mod h1:SKZx6stCn03JN3BOWTwvVIO2ajMkb/zQdTceXYhKw/4= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= +github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8= +github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWgejz1AlYpY1mI0= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= +github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxEmTbaqt1hkJ/t6skqEGYiMag343ucI= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= +github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= +github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w= +github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/sqids/sqids-go v0.4.1 h1:eQKYzmAZbLlRwHeHYPF35QhgxwZHLnlmVj9AkIj/rrw= +github.com/sqids/sqids-go v0.4.1/go.mod h1:EMwHuPQgSNFS0A49jESTfIQS+066XQTVhukrzEPScl8= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= +github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU= +github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= +github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= +github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= +github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +go.lsp.dev/jsonrpc2 v0.10.0 h1:Pr/YcXJoEOTMc/b6OTmcR1DPJ3mSWl/SWiU1Cct6VmI= +go.lsp.dev/jsonrpc2 v0.10.0/go.mod h1:fmEzIdXPi/rf6d4uFcayi8HpFP1nBF99ERP1htC72Ac= +go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 h1:hCzQgh6UcwbKgNSRurYWSqh8MufqRRPODRBblutn4TE= +go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2/go.mod h1:gtSHRuYfbCT0qnbLnovpie/WEmqyJ7T4n6VXiFMBtcw= +go.lsp.dev/protocol v0.12.0 h1:tNprUI9klQW5FAFVM4Sa+AbPFuVQByWhP1ttNUAjIWg= +go.lsp.dev/protocol v0.12.0/go.mod h1:Qb11/HgZQ72qQbeyPfJbu3hZBH23s1sr4st8czGeDMQ= +go.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo= +go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o= +golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= +modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc= +modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM= +modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= +modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE= +modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.67.7 h1:H+gYQw2PyidyxwxQsGTwQw6+6H+xUk+plvOKW7+d3TI= +modernc.org/libc v1.67.7/go.mod h1:UjCSJFl2sYbJbReVQeVpq/MgzlbmDM4cRHIYFelnaDk= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.45.0 h1:r51cSGzKpbptxnby+EIIz5fop4VuE4qFoVEjNvWoObs= +modernc.org/sqlite v1.45.0/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI= +mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk= +pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo= +pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o= diff --git a/interactions/admin/admin.go b/heimdallr/interactions/admin/admin.go similarity index 100% rename from interactions/admin/admin.go rename to heimdallr/interactions/admin/admin.go diff --git a/interactions/admin/anti_spam.go b/heimdallr/interactions/admin/anti_spam.go similarity index 100% rename from interactions/admin/anti_spam.go rename to heimdallr/interactions/admin/anti_spam.go diff --git a/interactions/admin/ban_footer.go b/heimdallr/interactions/admin/ban_footer.go similarity index 100% rename from interactions/admin/ban_footer.go rename to heimdallr/interactions/admin/ban_footer.go diff --git a/interactions/admin/gatekeep.go b/heimdallr/interactions/admin/gatekeep.go similarity index 100% rename from interactions/admin/gatekeep.go rename to heimdallr/interactions/admin/gatekeep.go diff --git a/interactions/admin/gatekeep_message.go b/heimdallr/interactions/admin/gatekeep_message.go similarity index 81% rename from interactions/admin/gatekeep_message.go rename to heimdallr/interactions/admin/gatekeep_message.go index 521bbdc..60fb4f7 100644 --- a/interactions/admin/gatekeep_message.go +++ b/heimdallr/interactions/admin/gatekeep_message.go @@ -42,8 +42,9 @@ func AdminGatekeepMessageHandler(e *handler.CommandEvent) error { } if hasReset && resetOption == "reset" { - // Reset the message to default settings.GatekeepApprovedMessage = "Welcome to the server, {{user}}!" + settings.GatekeepApprovedMessageV2 = false + settings.GatekeepApprovedMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { return err @@ -51,6 +52,14 @@ func AdminGatekeepMessageHandler(e *handler.CommandEvent) error { return e.CreateMessage(interactions.EphemeralMessageContent("Gatekeep approved message has been reset.")) } + if settings.GatekeepApprovedMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "The gatekeep approved message is currently using **Components V2** mode, which can only be edited from the web dashboard.\n\nUse the `reset` option to switch back to plain text mode.", + ), + ) + } + embed := discord.NewEmbedBuilder(). SetTitle("Gatekeep approved message"). SetDescription(settings.GatekeepApprovedMessage). @@ -81,6 +90,14 @@ func AdminGatekeepMessageButtonHandler(e *handler.ComponentEvent) error { return err } + if settings.GatekeepApprovedMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "This message uses Components V2 and can only be edited from the web dashboard.", + ), + ) + } + return e.Modal( messageModal( "/admin/gatekeep-message/modal", @@ -112,6 +129,8 @@ func AdminGatekeepMessageModalHandler(e *handler.ModalEvent) error { } settings.GatekeepApprovedMessage = message + settings.GatekeepApprovedMessageV2 = false + settings.GatekeepApprovedMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { diff --git a/interactions/admin/infractions.go b/heimdallr/interactions/admin/infractions.go similarity index 100% rename from interactions/admin/infractions.go rename to heimdallr/interactions/admin/infractions.go diff --git a/interactions/admin/join_leave.go b/heimdallr/interactions/admin/join_leave.go similarity index 100% rename from interactions/admin/join_leave.go rename to heimdallr/interactions/admin/join_leave.go diff --git a/interactions/admin/join_leave_messages.go b/heimdallr/interactions/admin/join_leave_messages.go similarity index 82% rename from interactions/admin/join_leave_messages.go rename to heimdallr/interactions/admin/join_leave_messages.go index 571c69e..a09178b 100644 --- a/interactions/admin/join_leave_messages.go +++ b/heimdallr/interactions/admin/join_leave_messages.go @@ -56,8 +56,9 @@ func AdminJoinMessageHandler(e *handler.CommandEvent) error { } if hasReset && resetOption == "reset" { - // Reset the message to default settings.JoinMessage = "Welcome to the server, {{user}}!" + settings.JoinMessageV2 = false + settings.JoinMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { return err @@ -65,6 +66,14 @@ func AdminJoinMessageHandler(e *handler.CommandEvent) error { return e.CreateMessage(interactions.EphemeralMessageContent("Join message has been reset.")) } + if settings.JoinMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "The join message is currently using **Components V2** mode, which can only be edited from the web dashboard.\n\nUse the `reset` option to switch back to plain text mode.", + ), + ) + } + embed := discord.NewEmbedBuilder(). SetTitle("Join message"). SetDescription(settings.JoinMessage). @@ -95,6 +104,14 @@ func AdminJoinMessageButtonHandler(e *handler.ComponentEvent) error { return err } + if settings.JoinMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "This message uses Components V2 and can only be edited from the web dashboard.", + ), + ) + } + return e.Modal( messageModal( "/admin/join-message/modal", @@ -128,6 +145,8 @@ func AdminJoinMessageModalHandler(e *handler.ModalEvent) error { } settings.JoinMessage = message + settings.JoinMessageV2 = false + settings.JoinMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { @@ -154,8 +173,9 @@ func AdminLeaveMessageHandler(e *handler.CommandEvent) error { } if hasReset && resetOption == "reset" { - // Reset the message to default settings.LeaveMessage = "{{user}} has left the server." + settings.LeaveMessageV2 = false + settings.LeaveMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { return err @@ -163,6 +183,14 @@ func AdminLeaveMessageHandler(e *handler.CommandEvent) error { return e.CreateMessage(interactions.EphemeralMessageContent("Leave message has been reset.")) } + if settings.LeaveMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "The leave message is currently using **Components V2** mode, which can only be edited from the web dashboard.\n\nUse the `reset` option to switch back to plain text mode.", + ), + ) + } + embed := discord.NewEmbedBuilder(). SetTitle("Leave message"). SetDescription(settings.LeaveMessage). @@ -193,6 +221,14 @@ func AdminLeaveMessageButtonHandler(e *handler.ComponentEvent) error { return err } + if settings.LeaveMessageV2 { + return e.CreateMessage( + interactions.EphemeralMessageContent( + "This message uses Components V2 and can only be edited from the web dashboard.", + ), + ) + } + return e.Modal( messageModal( "/admin/leave-message/modal", @@ -226,6 +262,8 @@ func AdminLeaveMessageModalHandler(e *handler.ModalEvent) error { } settings.LeaveMessage = message + settings.LeaveMessageV2 = false + settings.LeaveMessageV2Json = "" err = model.SetGuildSettings(settings) if err != nil { diff --git a/interactions/admin/mod_channel.go b/heimdallr/interactions/admin/mod_channel.go similarity index 100% rename from interactions/admin/mod_channel.go rename to heimdallr/interactions/admin/mod_channel.go diff --git a/heimdallr/interactions/admin_dashboard/admin_dashboard.go b/heimdallr/interactions/admin_dashboard/admin_dashboard.go new file mode 100644 index 0000000..9afcd5a --- /dev/null +++ b/heimdallr/interactions/admin_dashboard/admin_dashboard.go @@ -0,0 +1,58 @@ +package admin_dashboard + +import ( + "fmt" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/handler" + "github.com/disgoorg/omit" + "github.com/spf13/viper" + + "github.com/NLLCommunity/heimdallr/interactions" + "github.com/NLLCommunity/heimdallr/model" + "github.com/NLLCommunity/heimdallr/utils" +) + +func Register(r *handler.Mux) []discord.ApplicationCommandCreate { + r.Command("/admin-dashboard", AdminDashboardHandler) + + return []discord.ApplicationCommandCreate{AdminDashboardCommand} +} + +var AdminDashboardCommand = discord.SlashCommandCreate{ + Name: "admin-dashboard", + Description: "Get a login link for the web dashboard", + DefaultMemberPermissions: omit.NewPtr(discord.PermissionAdministrator), + Contexts: []discord.InteractionContextType{discord.InteractionContextTypeGuild}, + IntegrationTypes: []discord.ApplicationIntegrationType{discord.ApplicationIntegrationTypeGuildInstall}, +} + +func AdminDashboardHandler(e *handler.CommandEvent) error { + utils.LogInteraction("admin-dashboard", e) + + user := e.User() + + var avatar string + if user.Avatar != nil { + avatar = *user.Avatar + } + + code, err := model.CreateLoginCode(user.ID, user.Username, avatar) + if err != nil { + return e.CreateMessage( + interactions.EphemeralMessageContent("Failed to generate login link. Please try again."), + ) + } + + baseURL := viper.GetString("dashboard.base_url") + link := fmt.Sprintf("%s/#/callback?code=%s", baseURL, code) + + message := fmt.Sprintf( + "**Dashboard Login Link**\n\n"+ + "[Click here to open the dashboard](%s)\n\n"+ + "This link expires in **5 minutes** and can only be used once.", + link, + ) + + return e.CreateMessage(interactions.EphemeralMessageContent(message)) +} diff --git a/interactions/ban/ban.go b/heimdallr/interactions/ban/ban.go similarity index 100% rename from interactions/ban/ban.go rename to heimdallr/interactions/ban/ban.go diff --git a/interactions/gatekeep/gatekeep.go b/heimdallr/interactions/gatekeep/gatekeep.go similarity index 66% rename from interactions/gatekeep/gatekeep.go rename to heimdallr/interactions/gatekeep/gatekeep.go index f533e8e..6f4ba28 100644 --- a/interactions/gatekeep/gatekeep.go +++ b/heimdallr/interactions/gatekeep/gatekeep.go @@ -3,9 +3,11 @@ package gatekeep import ( "fmt" "log/slog" + "strings" "sync" "github.com/cbroglie/mustache" + "github.com/disgoorg/disgo/bot" "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/handler" "github.com/disgoorg/disgo/rest" @@ -146,7 +148,10 @@ func approvedInnerHandler(e *handler.CommandEvent, guild discord.Guild, member d "guild_id", guild.ID, ) - if guildSettings.GatekeepApprovedMessage == "" { + hasV2 := guildSettings.GatekeepApprovedMessageV2 && guildSettings.GatekeepApprovedMessageV2Json != "" + hasPlain := guildSettings.GatekeepApprovedMessage != "" + + if !hasV2 && !hasPlain { slog.Info("No approved message set; not sending message.") return e.CreateMessage( interactions.EphemeralMessageContent( @@ -155,44 +160,105 @@ func approvedInnerHandler(e *handler.CommandEvent, guild discord.Guild, member d ) } - channel := guildSettings.JoinLeaveChannel - if channel == 0 { - if guild.SystemChannelID != nil { - channel = *guild.SystemChannelID - } + templateData := utils.NewMessageTemplateData(member.Member, guild) + + data := &gatekeepData{ + approver: e.User(), + client: e.Client(), + guild: guild, + member: member, + guildSettings: guildSettings, + templateData: templateData, } - templateData := utils.NewMessageTemplateData(member.Member, guild) - contents, err := mustache.RenderRaw(guildSettings.GatekeepApprovedMessage, true, templateData) + if hasV2 { + _, err = createV2ApprovedMessage(data) + } else { + _, err = createV1Approvedtmessage(data) + } if err != nil { - slog.Warn("Failed to render approved message template.") + _, err = e.CreateFollowupMessage( + interactions.EphemeralMessageContent( + "Failed to send message to approved user.", + ), + ) return err } - _, err = e.Client().Rest.CreateMessage( + + _, err = e.CreateFollowupMessage( + interactions.EphemeralMessageContent( + "User has been approved!", + ), + ) + return err +} + +type gatekeepData struct { + approver discord.User + client *bot.Client + guild discord.Guild + member discord.ResolvedMember + guildSettings *model.GuildSettings + templateData utils.MessageTemplateData +} + +func createV1Approvedtmessage( + data *gatekeepData, +) (m *discord.Message, err error) { + contents, renderErr := mustache.RenderRaw(data.guildSettings.GatekeepApprovedMessage, true, data.templateData) + if renderErr != nil { + slog.Warn("Failed to render approved message template.") + return nil, renderErr + } + + channel := data.guildSettings.JoinLeaveChannel + if channel == 0 && data.guild.SystemChannelID != nil { + channel = *data.guild.SystemChannelID + } + + return data.client.Rest.CreateMessage( channel, discord.NewMessageCreate(). WithContent( contents+ - fmt.Sprintf("\n\n-# Approved by %s", e.User().Mention()), + fmt.Sprintf("\n\n-# Approved by %s", data.approver.Mention()), ). WithAllowedMentions( &discord.AllowedMentions{ - Users: []snowflake.ID{member.User.ID}, + Users: []snowflake.ID{data.member.User.ID}, }, ), ) - if err != nil { - return e.CreateMessage( - interactions.EphemeralMessageContent( - "Failed to send message to approved user.", - ), - ) +} + +func createV2ApprovedMessage( + data *gatekeepData, +) (m *discord.Message, err error) { + emojiMap := make(map[string]discord.Emoji) + for emoji := range data.client.Caches.Emojis(data.guild.ID) { + emojiMap[strings.ToLower(emoji.Name)] = emoji } - _, err = e.CreateFollowupMessage( - interactions.EphemeralMessageContent( - "User has been approved!", - ), - ) - return err + components, compErr := utils.BuildV2Message(data.guildSettings.GatekeepApprovedMessageV2Json, data.templateData, emojiMap) + if compErr != nil { + slog.Warn("Failed to build V2 approved message.", "err", compErr) + return nil, compErr + } + + components = append(components, discord.NewTextDisplay( + fmt.Sprintf("-# Approved by %s", data.approver.Mention()), + )) + + channel := data.guildSettings.JoinLeaveChannel + if channel == 0 && data.guild.SystemChannelID != nil { + channel = *data.guild.SystemChannelID + } + + return data.client.Rest.CreateMessage(channel, discord.MessageCreate{ + Flags: discord.MessageFlagIsComponentsV2, + Components: components, + AllowedMentions: &discord.AllowedMentions{ + Users: []snowflake.ID{data.member.User.ID}, + }, + }) } diff --git a/interactions/gatekeep/slash_command.go b/heimdallr/interactions/gatekeep/slash_command.go similarity index 100% rename from interactions/gatekeep/slash_command.go rename to heimdallr/interactions/gatekeep/slash_command.go diff --git a/interactions/gatekeep/user_command.go b/heimdallr/interactions/gatekeep/user_command.go similarity index 100% rename from interactions/gatekeep/user_command.go rename to heimdallr/interactions/gatekeep/user_command.go diff --git a/interactions/infractions/infractions.go b/heimdallr/interactions/infractions/infractions.go similarity index 100% rename from interactions/infractions/infractions.go rename to heimdallr/interactions/infractions/infractions.go diff --git a/interactions/infractions/infractions_command.go b/heimdallr/interactions/infractions/infractions_command.go similarity index 100% rename from interactions/infractions/infractions_command.go rename to heimdallr/interactions/infractions/infractions_command.go diff --git a/interactions/infractions/warn_command.go b/heimdallr/interactions/infractions/warn_command.go similarity index 100% rename from interactions/infractions/warn_command.go rename to heimdallr/interactions/infractions/warn_command.go diff --git a/interactions/infractions/warnings_command.go b/heimdallr/interactions/infractions/warnings_command.go similarity index 100% rename from interactions/infractions/warnings_command.go rename to heimdallr/interactions/infractions/warnings_command.go diff --git a/interactions/interactions.go b/heimdallr/interactions/interactions.go similarity index 100% rename from interactions/interactions.go rename to heimdallr/interactions/interactions.go diff --git a/interactions/interactions_test.go b/heimdallr/interactions/interactions_test.go similarity index 100% rename from interactions/interactions_test.go rename to heimdallr/interactions/interactions_test.go diff --git a/interactions/kick/kick.go b/heimdallr/interactions/kick/kick.go similarity index 100% rename from interactions/kick/kick.go rename to heimdallr/interactions/kick/kick.go diff --git a/interactions/modmail/button_modal_handler.go b/heimdallr/interactions/modmail/button_modal_handler.go similarity index 100% rename from interactions/modmail/button_modal_handler.go rename to heimdallr/interactions/modmail/button_modal_handler.go diff --git a/interactions/modmail/modmail.go b/heimdallr/interactions/modmail/modmail.go similarity index 100% rename from interactions/modmail/modmail.go rename to heimdallr/interactions/modmail/modmail.go diff --git a/interactions/modmail/modmail_admin_button.go b/heimdallr/interactions/modmail/modmail_admin_button.go similarity index 100% rename from interactions/modmail/modmail_admin_button.go rename to heimdallr/interactions/modmail/modmail_admin_button.go diff --git a/interactions/modmail/report_message.go b/heimdallr/interactions/modmail/report_message.go similarity index 100% rename from interactions/modmail/report_message.go rename to heimdallr/interactions/modmail/report_message.go diff --git a/interactions/ping/ping.go b/heimdallr/interactions/ping/ping.go similarity index 100% rename from interactions/ping/ping.go rename to heimdallr/interactions/ping/ping.go diff --git a/interactions/ping/ping_test.go b/heimdallr/interactions/ping/ping_test.go similarity index 100% rename from interactions/ping/ping_test.go rename to heimdallr/interactions/ping/ping_test.go diff --git a/interactions/prune/prune.go b/heimdallr/interactions/prune/prune.go similarity index 100% rename from interactions/prune/prune.go rename to heimdallr/interactions/prune/prune.go diff --git a/interactions/quote/quote.go b/heimdallr/interactions/quote/quote.go similarity index 100% rename from interactions/quote/quote.go rename to heimdallr/interactions/quote/quote.go diff --git a/interactions/role_button/button_component.go b/heimdallr/interactions/role_button/button_component.go similarity index 100% rename from interactions/role_button/button_component.go rename to heimdallr/interactions/role_button/button_component.go diff --git a/interactions/role_button/create_command.go b/heimdallr/interactions/role_button/create_command.go similarity index 100% rename from interactions/role_button/create_command.go rename to heimdallr/interactions/role_button/create_command.go diff --git a/interactions/role_button/role_button.go b/heimdallr/interactions/role_button/role_button.go similarity index 100% rename from interactions/role_button/role_button.go rename to heimdallr/interactions/role_button/role_button.go diff --git a/listeners/antispam_message.go b/heimdallr/listeners/antispam_message.go similarity index 100% rename from listeners/antispam_message.go rename to heimdallr/listeners/antispam_message.go diff --git a/listeners/audit_log.go b/heimdallr/listeners/audit_log.go similarity index 100% rename from listeners/audit_log.go rename to heimdallr/listeners/audit_log.go diff --git a/listeners/ban.go b/heimdallr/listeners/ban.go similarity index 100% rename from listeners/ban.go rename to heimdallr/listeners/ban.go diff --git a/listeners/gatekeep_join.go b/heimdallr/listeners/gatekeep_join.go similarity index 100% rename from listeners/gatekeep_join.go rename to heimdallr/listeners/gatekeep_join.go diff --git a/heimdallr/listeners/joinleave.go b/heimdallr/listeners/joinleave.go new file mode 100644 index 0000000..f78ea27 --- /dev/null +++ b/heimdallr/listeners/joinleave.go @@ -0,0 +1,166 @@ +package listeners + +import ( + "log/slog" + "strings" + + "github.com/cbroglie/mustache" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" + + "github.com/NLLCommunity/heimdallr/model" + "github.com/NLLCommunity/heimdallr/utils" +) + +func OnUserJoin(e *events.GuildMemberJoin) { + guildID := e.GuildID + guild, err := e.Client().Rest.GetGuild(guildID, false) + if err != nil { + return + } + + guildSettings, err := model.GetGuildSettings(guildID) + if err != nil { + return + } + + if !guildSettings.JoinMessageEnabled { + return + } + + joinLeaveChannel := guildSettings.JoinLeaveChannel + if joinLeaveChannel == 0 && guild.SystemChannelID != nil { + joinLeaveChannel = *guild.SystemChannelID + } + if joinLeaveChannel == 0 { + return + } + + joinleaveInfo := utils.NewMessageTemplateData(e.Member, guild.Guild) + + hasV2 := guildSettings.JoinMessageV2 && guildSettings.JoinMessageV2Json != "" + + if hasV2 { + emojiMap := make(map[string]discord.Emoji) + for emoji := range e.Client().Caches.Emojis(guildID) { + emojiMap[strings.ToLower(emoji.Name)] = emoji + } + + _, err = createV2Message(joinleaveInfo, emojiMap, guildSettings.JoinMessageV2Json, guildID, joinLeaveChannel, e.Client()) + } else { + _, err = createV1Message(joinleaveInfo, guildSettings.JoinMessage, guildID, joinLeaveChannel, e.Client()) + } + + if err != nil { + slog.Error( + "Failed to send join message.", + "guild_id", guildID, + "channel_id", joinLeaveChannel, + "err", err, + ) + } +} + +func OnUserLeave(e *events.GuildMemberLeave) { + guildID := e.GuildID + guild, err := e.Client().Rest.GetGuild(guildID, false) + if err != nil { + return + } + + guildSettings, err := model.GetGuildSettings(guildID) + if err != nil { + return + } + + if !guildSettings.LeaveMessageEnabled { + return + } + + joinLeaveChannel := guildSettings.JoinLeaveChannel + if joinLeaveChannel == 0 && guild.SystemChannelID != nil { + joinLeaveChannel = *guild.SystemChannelID + } + if joinLeaveChannel == 0 { + return + } + + if pruned, _ := model.IsMemberPruned(guildID, e.User.ID); pruned { + return + } + + e.Member.User = e.User + joinleaveInfo := utils.NewMessageTemplateData(e.Member, guild.Guild) + + hasV2 := guildSettings.LeaveMessageV2 && guildSettings.LeaveMessageV2Json != "" + + if hasV2 { + emojiMap := make(map[string]discord.Emoji) + for emoji := range e.Client().Caches.Emojis(guildID) { + emojiMap[strings.ToLower(emoji.Name)] = emoji + } + + _, err = createV2Message(joinleaveInfo, emojiMap, guildSettings.LeaveMessageV2Json, guildID, joinLeaveChannel, e.Client()) + } else { + _, err = createV1Message(joinleaveInfo, guildSettings.LeaveMessage, guildID, joinLeaveChannel, e.Client()) + } + + if err != nil { + slog.Error( + "Failed to send leave message.", + "guild_id", guildID, + "channel_id", joinLeaveChannel, + "err", err, + ) + } +} + +func createV1Message( + data utils.MessageTemplateData, + messageTemplate string, + guildID snowflake.ID, + channelID snowflake.ID, + client *bot.Client, +) (m *discord.Message, err error) { + + contents, err := mustache.RenderRaw(messageTemplate, true, data) + if err != nil { + slog.Error("Failed to render V1 join message template.", "err", err, "guild_id", guildID) + return + } + + m, err = client.Rest.CreateMessage( + channelID, discord.NewMessageCreate().WithContent(contents), + ) + if err != nil { + slog.Error("Failed to send V1 join message.", "guild_id", guildID, "channel_id", channelID, "err", err) + } + return +} + +func createV2Message( + data utils.MessageTemplateData, + emojiMap map[string]discord.Emoji, + messageJson string, + guildID snowflake.ID, + channelID snowflake.ID, + client *bot.Client, +) (m *discord.Message, err error) { + + components, err := utils.BuildV2Message(messageJson, data, emojiMap) + if err != nil { + slog.Error("Failed to build V2 join message.", "err", err, "guild_id", guildID) + return + } + + m, err = client.Rest.CreateMessage(channelID, discord.MessageCreate{ + Flags: discord.MessageFlagIsComponentsV2, + Components: components, + }) + if err != nil { + slog.Error("Failed to send V2 join message.", "guild_id", guildID, "channel_id", channelID, "err", err) + } + return +} diff --git a/listeners/notify_on_warned_user_join.go b/heimdallr/listeners/notify_on_warned_user_join.go similarity index 100% rename from listeners/notify_on_warned_user_join.go rename to heimdallr/listeners/notify_on_warned_user_join.go diff --git a/main.go b/heimdallr/main.go similarity index 94% rename from main.go rename to heimdallr/main.go index 4c54cf5..e1b2757 100644 --- a/main.go +++ b/heimdallr/main.go @@ -24,6 +24,7 @@ import ( _ "github.com/NLLCommunity/heimdallr/config" "github.com/NLLCommunity/heimdallr/interactions" "github.com/NLLCommunity/heimdallr/interactions/admin" + "github.com/NLLCommunity/heimdallr/interactions/admin_dashboard" "github.com/NLLCommunity/heimdallr/interactions/ban" "github.com/NLLCommunity/heimdallr/interactions/gatekeep" "github.com/NLLCommunity/heimdallr/interactions/infractions" @@ -35,6 +36,7 @@ import ( "github.com/NLLCommunity/heimdallr/interactions/role_button" "github.com/NLLCommunity/heimdallr/listeners" "github.com/NLLCommunity/heimdallr/model" + "github.com/NLLCommunity/heimdallr/rpcserver" "github.com/NLLCommunity/heimdallr/scheduled_tasks" ) @@ -83,6 +85,7 @@ func main() { commandInteractions := []interactions.ApplicationCommandRegisterFunc{ admin.Register, + admin_dashboard.Register, ban.Register, gatekeep.Register, infractions.Register, @@ -159,6 +162,12 @@ func main() { removeTempBansTask := scheduled_tasks.RemoveTempBansScheduledTask(client) removeStalePrunesTask := scheduled_tasks.RemoveStalePendingPrunes() + go func() { + if err := rpcserver.StartServer(viper.GetString("web.address"), client); err != nil { + slog.Error("Failed to start RPC server", "error", err) + } + }() + s := make(chan os.Signal, 1) signal.Notify(s, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) <-s diff --git a/main_test.go b/heimdallr/main_test.go similarity index 100% rename from main_test.go rename to heimdallr/main_test.go diff --git a/model/birthday.go b/heimdallr/model/birthday.go similarity index 100% rename from model/birthday.go rename to heimdallr/model/birthday.go diff --git a/heimdallr/model/dashboard_session.go b/heimdallr/model/dashboard_session.go new file mode 100644 index 0000000..b52784d --- /dev/null +++ b/heimdallr/model/dashboard_session.go @@ -0,0 +1,131 @@ +package model + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "errors" + "time" + + "github.com/disgoorg/snowflake/v2" + "gorm.io/gorm" +) + +// tokenHash returns the hex-encoded SHA-256 of a session token. +// The DB stores only this hash; the raw token lives only in the cookie. +func tokenHash(token string) string { + h := sha256.Sum256([]byte(token)) + return hex.EncodeToString(h[:]) +} + +const ( + loginCodeExpiry = 5 * time.Minute + sessionExpiry = 24 * time.Hour +) + +type DashboardLoginCode struct { + Code string `gorm:"primaryKey"` + UserID snowflake.ID + Username string + Avatar string + ExpiresAt time.Time +} + +type DashboardSession struct { + Token string `gorm:"primaryKey"` + UserID snowflake.ID `gorm:"index"` + Username string + Avatar string + ExpiresAt time.Time +} + +func CreateLoginCode(userID snowflake.ID, username, avatar string) (string, error) { + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + return "", err + } + code := hex.EncodeToString(b) + + loginCode := DashboardLoginCode{ + Code: code, + UserID: userID, + Username: username, + Avatar: avatar, + ExpiresAt: time.Now().Add(loginCodeExpiry), + } + if err := DB.Create(&loginCode).Error; err != nil { + return "", err + } + return code, nil +} + +func ExchangeLoginCode(code string) (*DashboardSession, error) { + var session *DashboardSession + + err := DB.Transaction(func(tx *gorm.DB) error { + var loginCode DashboardLoginCode + if err := tx.Where("code = ? AND expires_at > ?", code, time.Now()).First(&loginCode).Error; err != nil { + return errors.New("invalid or expired login code") + } + + // Atomically delete the login code and verify we actually deleted it. + // If RowsAffected == 0, a concurrent request already consumed it. + result := tx.Delete(&loginCode) + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return errors.New("invalid or expired login code") + } + + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + return err + } + rawToken := hex.EncodeToString(b) + + dbSession := DashboardSession{ + Token: tokenHash(rawToken), // store hash, never the raw token + UserID: loginCode.UserID, + Username: loginCode.Username, + Avatar: loginCode.Avatar, + ExpiresAt: time.Now().Add(sessionExpiry), + } + if err := tx.Create(&dbSession).Error; err != nil { + return err + } + + // Return the raw token to the caller for use in the session cookie. + // The DB record holds only the hash. + session = &DashboardSession{ + Token: rawToken, + UserID: dbSession.UserID, + Username: dbSession.Username, + Avatar: dbSession.Avatar, + ExpiresAt: dbSession.ExpiresAt, + } + return nil + }) + if err != nil { + return nil, err + } + return session, nil +} + +func GetSession(token string) (*DashboardSession, error) { + var session DashboardSession + if err := DB.Where("token = ? AND expires_at > ?", tokenHash(token), time.Now()).First(&session).Error; err != nil { + return nil, errors.New("invalid or expired session") + } + return &session, nil +} + +func DeleteSession(token string) error { + return DB.Where("token = ?", tokenHash(token)).Delete(&DashboardSession{}).Error +} + +func CleanExpiredSessions() { + now := time.Now() + DB.Where("expires_at <= ?", now).Delete(&DashboardLoginCode{}) + DB.Where("expires_at <= ?", now).Delete(&DashboardSession{}) +} diff --git a/model/deleted_message_log.go b/heimdallr/model/deleted_message_log.go similarity index 100% rename from model/deleted_message_log.go rename to heimdallr/model/deleted_message_log.go diff --git a/model/guild_settings.go b/heimdallr/model/guild_settings.go similarity index 80% rename from model/guild_settings.go rename to heimdallr/model/guild_settings.go index 63369a5..68c7314 100644 --- a/model/guild_settings.go +++ b/heimdallr/model/guild_settings.go @@ -20,16 +20,22 @@ type GuildSettings struct { NotifyOnWarnedUserJoin bool NotifyWarnSeverityThreshold float64 `gorm:"default:1.0"` - GatekeepEnabled bool - GatekeepPendingRole snowflake.ID - GatekeepApprovedRole snowflake.ID - GatekeepAddPendingRoleOnJoin bool - GatekeepApprovedMessage string + GatekeepEnabled bool + GatekeepPendingRole snowflake.ID + GatekeepApprovedRole snowflake.ID + GatekeepAddPendingRoleOnJoin bool + GatekeepApprovedMessage string + GatekeepApprovedMessageV2 bool + GatekeepApprovedMessageV2Json string JoinMessageEnabled bool JoinMessage string + JoinMessageV2 bool + JoinMessageV2Json string LeaveMessageEnabled bool LeaveMessage string + LeaveMessageV2 bool + LeaveMessageV2Json string JoinLeaveChannel snowflake.ID AntiSpamEnabled bool diff --git a/model/infractions.go b/heimdallr/model/infractions.go similarity index 100% rename from model/infractions.go rename to heimdallr/model/infractions.go diff --git a/model/model.go b/heimdallr/model/model.go similarity index 93% rename from model/model.go rename to heimdallr/model/model.go index a3e9572..dbd6164 100644 --- a/model/model.go +++ b/heimdallr/model/model.go @@ -32,6 +32,8 @@ func InitDB(path string) (*gorm.DB, error) { &ModmailSettings{}, &TempBan{}, &MemberPendingPrune{}, + &DashboardLoginCode{}, + &DashboardSession{}, ) if err != nil { slog.Error("failed to migrate database", "error", err) diff --git a/model/model_test.go b/heimdallr/model/model_test.go similarity index 100% rename from model/model_test.go rename to heimdallr/model/model_test.go diff --git a/model/modmail_settings.go b/heimdallr/model/modmail_settings.go similarity index 100% rename from model/modmail_settings.go rename to heimdallr/model/modmail_settings.go diff --git a/model/pending_prune.go b/heimdallr/model/pending_prune.go similarity index 100% rename from model/pending_prune.go rename to heimdallr/model/pending_prune.go diff --git a/model/temp_bans.go b/heimdallr/model/temp_bans.go similarity index 100% rename from model/temp_bans.go rename to heimdallr/model/temp_bans.go diff --git a/heimdallr/proto/greet/v1/greet.proto b/heimdallr/proto/greet/v1/greet.proto new file mode 100644 index 0000000..109fa41 --- /dev/null +++ b/heimdallr/proto/greet/v1/greet.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package greet.v1; + +import "buf/validate/validate.proto"; + +message GreetRequest { + string name = 1 [(buf.validate.field).string = { + min_len: 1, + max_len: 50, + }]; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} diff --git a/heimdallr/proto/heimdallr/v1/auth.proto b/heimdallr/proto/heimdallr/v1/auth.proto new file mode 100644 index 0000000..43ea9b7 --- /dev/null +++ b/heimdallr/proto/heimdallr/v1/auth.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +package heimdallr.v1; + +message User { + string id = 1; + string username = 2; + string avatar = 3; +} + +message Guild { + string id = 1; + string name = 2; + string icon = 3; +} + +message GetLoginURLRequest {} + +message GetLoginURLResponse { + string url = 1; +} + +message ExchangeCodeRequest { + string code = 1; +} + +message ExchangeCodeResponse { + User user = 2; +} + +message GetCurrentUserRequest {} + +message GetCurrentUserResponse { + User user = 1; +} + +message ListGuildsRequest {} + +message ListGuildsResponse { + repeated Guild guilds = 1; +} + +message LogoutRequest {} + +message LogoutResponse {} + +service AuthService { + rpc GetLoginURL(GetLoginURLRequest) returns (GetLoginURLResponse); + rpc ExchangeCode(ExchangeCodeRequest) returns (ExchangeCodeResponse); + rpc GetCurrentUser(GetCurrentUserRequest) returns (GetCurrentUserResponse); + rpc ListGuilds(ListGuildsRequest) returns (ListGuildsResponse); + rpc Logout(LogoutRequest) returns (LogoutResponse); +} diff --git a/heimdallr/proto/heimdallr/v1/guild_settings.proto b/heimdallr/proto/heimdallr/v1/guild_settings.proto new file mode 100644 index 0000000..f101f5b --- /dev/null +++ b/heimdallr/proto/heimdallr/v1/guild_settings.proto @@ -0,0 +1,208 @@ +syntax = "proto3"; + +package heimdallr.v1; + +// ModChannel +message GetModChannelRequest { + string guild_id = 1; +} + +message UpdateModChannelRequest { + ModChannelSettings settings = 1; +} + +message ModChannelSettings { + string guild_id = 1; + string moderator_channel = 2; +} + +// InfractionSettings +message GetInfractionSettingsRequest { + string guild_id = 1; +} + +message UpdateInfractionSettingsRequest { + InfractionSettings settings = 1; +} + +message InfractionSettings { + string guild_id = 1; + double half_life_days = 2; + bool notify_on_warned_user_join = 3; + double notify_warn_severity_threshold = 4; +} + +// GatekeepSettings +message GetGatekeepSettingsRequest { + string guild_id = 1; +} + +message UpdateGatekeepSettingsRequest { + GatekeepSettings settings = 1; +} + +message GatekeepSettings { + string guild_id = 1; + bool enabled = 2; + string pending_role = 3; + string approved_role = 4; + bool add_pending_role_on_join = 5; + string approved_message = 6; + bool approved_message_v2 = 7; + string approved_message_v2_json = 8; +} + +// JoinLeaveSettings +message GetJoinLeaveSettingsRequest { + string guild_id = 1; +} + +message UpdateJoinLeaveSettingsRequest { + JoinLeaveSettings settings = 1; +} + +message JoinLeaveSettings { + string guild_id = 1; + bool join_message_enabled = 2; + string join_message = 3; + bool leave_message_enabled = 4; + string leave_message = 5; + string channel = 6; + bool join_message_v2 = 7; + string join_message_v2_json = 8; + bool leave_message_v2 = 9; + string leave_message_v2_json = 10; +} + +// AntiSpamSettings +message GetAntiSpamSettingsRequest { + string guild_id = 1; +} + +message UpdateAntiSpamSettingsRequest { + AntiSpamSettings settings = 1; +} + +message AntiSpamSettings { + string guild_id = 1; + bool enabled = 2; + int32 count = 3; + int32 cooldown_seconds = 4; +} + +// BanFooterSettings +message GetBanFooterSettingsRequest { + string guild_id = 1; +} + +message UpdateBanFooterSettingsRequest { + BanFooterSettings settings = 1; +} + +message BanFooterSettings { + string guild_id = 1; + string footer = 2; + bool always_send = 3; +} + +// ModmailSettings +message GetModmailSettingsRequest { + string guild_id = 1; +} + +message UpdateModmailSettingsRequest { + ModmailSettings settings = 1; +} + +message ModmailSettings { + string guild_id = 1; + string report_threads_channel = 2; + string report_notification_channel = 3; + string report_ping_role = 4; +} + +// Guild data (channels & roles) +message Channel { + string id = 1; + string name = 2; + int32 type = 3; + int32 position = 4; + string parent_id = 5; +} + +message Role { + string id = 1; + string name = 2; + int32 color = 3; + int32 position = 4; + bool managed = 5; +} + +message ListChannelsRequest { + string guild_id = 1; +} + +message ListChannelsResponse { + repeated Channel channels = 1; +} + +message ListRolesRequest { + string guild_id = 1; +} + +message ListRolesResponse { + repeated Role roles = 1; +} + +// SendComponentsMessage +message SendComponentsMessageRequest { + string guild_id = 1; + string channel_id = 2; + string components_json = 3; // JSON array of discord LayoutComponents +} + +message SendComponentsMessageResponse { + string message_id = 1; +} + +// Template placeholders +message TemplatePlaceholder { + string placeholder = 1; + string description = 2; +} + +message GetTemplatePlaceholdersRequest {} + +message GetTemplatePlaceholdersResponse { + repeated TemplatePlaceholder placeholders = 1; +} + +service GuildSettingsService { + rpc GetModChannel(GetModChannelRequest) returns (ModChannelSettings); + rpc UpdateModChannel(UpdateModChannelRequest) returns (ModChannelSettings); + + rpc GetInfractionSettings(GetInfractionSettingsRequest) returns (InfractionSettings); + rpc UpdateInfractionSettings(UpdateInfractionSettingsRequest) returns (InfractionSettings); + + rpc GetGatekeepSettings(GetGatekeepSettingsRequest) returns (GatekeepSettings); + rpc UpdateGatekeepSettings(UpdateGatekeepSettingsRequest) returns (GatekeepSettings); + + rpc GetJoinLeaveSettings(GetJoinLeaveSettingsRequest) returns (JoinLeaveSettings); + rpc UpdateJoinLeaveSettings(UpdateJoinLeaveSettingsRequest) returns (JoinLeaveSettings); + + rpc GetAntiSpamSettings(GetAntiSpamSettingsRequest) returns (AntiSpamSettings); + rpc UpdateAntiSpamSettings(UpdateAntiSpamSettingsRequest) returns (AntiSpamSettings); + + rpc GetBanFooterSettings(GetBanFooterSettingsRequest) returns (BanFooterSettings); + rpc UpdateBanFooterSettings(UpdateBanFooterSettingsRequest) returns (BanFooterSettings); + + rpc GetModmailSettings(GetModmailSettingsRequest) returns (ModmailSettings); + rpc UpdateModmailSettings(UpdateModmailSettingsRequest) returns (ModmailSettings); + + rpc ListChannels(ListChannelsRequest) returns (ListChannelsResponse); + rpc ListRoles(ListRolesRequest) returns (ListRolesResponse); + + rpc GetTemplatePlaceholders(GetTemplatePlaceholdersRequest) returns (GetTemplatePlaceholdersResponse); + + rpc SendComponentsMessage(SendComponentsMessageRequest) returns (SendComponentsMessageResponse); +} diff --git a/rm_commands.go b/heimdallr/rm_commands.go similarity index 100% rename from rm_commands.go rename to heimdallr/rm_commands.go diff --git a/heimdallr/rpcserver/auth_interceptor.go b/heimdallr/rpcserver/auth_interceptor.go new file mode 100644 index 0000000..945ed06 --- /dev/null +++ b/heimdallr/rpcserver/auth_interceptor.go @@ -0,0 +1,102 @@ +//go:build web + +package rpcserver + +import ( + "context" + "net/http" + "strings" + + "connectrpc.com/connect" + + "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1/heimdallrv1connect" + "github.com/NLLCommunity/heimdallr/model" +) + +type sessionContextKey struct{} + +func SessionFromContext(ctx context.Context) *model.DashboardSession { + session, _ := ctx.Value(sessionContextKey{}).(*model.DashboardSession) + return session +} + +// cookieJarKey is the context key for the mutable cookie jar. +type cookieJarKey struct{} + +// cookieJar holds cookies to be set on the HTTP response. +type cookieJar struct { + cookies []*http.Cookie +} + +// SetResponseCookie schedules a Set-Cookie header on the response. +// Must be called from a handler running inside newCookieInterceptor. +func SetResponseCookie(ctx context.Context, cookie *http.Cookie) { + jar, ok := ctx.Value(cookieJarKey{}).(*cookieJar) + if ok { + jar.cookies = append(jar.cookies, cookie) + } +} + +// newCookieInterceptor injects a cookie jar into the context and writes +// any accumulated Set-Cookie headers onto the Connect response. +func newCookieInterceptor() connect.UnaryInterceptorFunc { + return func(next connect.UnaryFunc) connect.UnaryFunc { + return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { + jar := &cookieJar{} + ctx = context.WithValue(ctx, cookieJarKey{}, jar) + resp, err := next(ctx, req) + if resp != nil { + for _, c := range jar.cookies { + resp.Header().Add("Set-Cookie", c.String()) + } + } + return resp, err + } + } +} + +func newAuthInterceptor() connect.UnaryInterceptorFunc { + return func(next connect.UnaryFunc) connect.UnaryFunc { + return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { + // Skip auth for ExchangeCode and GetLoginURL — no token yet. + if req.Spec().Procedure == heimdallrv1connect.AuthServiceExchangeCodeProcedure || + req.Spec().Procedure == heimdallrv1connect.AuthServiceGetLoginURLProcedure { + return next(ctx, req) + } + + // Try cookie first, fall back to Authorization header. + token := tokenFromCookie(req.Header()) + if token == "" { + token = strings.TrimPrefix(req.Header().Get("Authorization"), "Bearer ") + } + if token == "" { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + session, err := model.GetSession(token) + if err != nil { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + ctx = context.WithValue(ctx, sessionContextKey{}, session) + return next(ctx, req) + } + } +} + +const sessionCookieName = "heimdallr_session" + +func tokenFromCookie(h http.Header) string { + raw := h.Get("Cookie") + if raw == "" { + return "" + } + // Parse cookies from the header. + header := http.Header{"Cookie": {raw}} + request := http.Request{Header: header} + c, err := request.Cookie(sessionCookieName) + if err != nil { + return "" + } + return c.Value +} diff --git a/heimdallr/rpcserver/auth_service.go b/heimdallr/rpcserver/auth_service.go new file mode 100644 index 0000000..3ba74de --- /dev/null +++ b/heimdallr/rpcserver/auth_service.go @@ -0,0 +1,124 @@ +//go:build web + +package rpcserver + +import ( + "context" + "errors" + "log/slog" + "net/http" + "strings" + + "connectrpc.com/connect" + "github.com/disgoorg/disgo/bot" + "github.com/spf13/viper" + + heimdallrv1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + "github.com/NLLCommunity/heimdallr/model" +) + +type authService struct { + client *bot.Client +} + +func (s *authService) GetLoginURL(_ context.Context, _ *heimdallrv1.GetLoginURLRequest) (*heimdallrv1.GetLoginURLResponse, error) { + return nil, connect.NewError( + connect.CodeUnimplemented, + errors.New("use the /admin-dashboard command in Discord to get a login link"), + ) +} + +func (s *authService) ExchangeCode(ctx context.Context, req *heimdallrv1.ExchangeCodeRequest) (*heimdallrv1.ExchangeCodeResponse, error) { + session, err := model.ExchangeLoginCode(req.GetCode()) + if err != nil { + return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("invalid or expired login code")) + } + + // Set session token as an HttpOnly cookie. + SetResponseCookie(ctx, makeSessionCookie(session.Token, 86400)) + + return &heimdallrv1.ExchangeCodeResponse{ + User: &heimdallrv1.User{ + Id: session.UserID.String(), + Username: session.Username, + Avatar: session.Avatar, + }, + }, nil +} + +func (s *authService) GetCurrentUser(ctx context.Context, _ *heimdallrv1.GetCurrentUserRequest) (*heimdallrv1.GetCurrentUserResponse, error) { + session := SessionFromContext(ctx) + if session == nil { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + return &heimdallrv1.GetCurrentUserResponse{ + User: &heimdallrv1.User{ + Id: session.UserID.String(), + Username: session.Username, + Avatar: session.Avatar, + }, + }, nil +} + +func (s *authService) ListGuilds(ctx context.Context, _ *heimdallrv1.ListGuildsRequest) (*heimdallrv1.ListGuildsResponse, error) { + session := SessionFromContext(ctx) + if session == nil { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + var guilds []*heimdallrv1.Guild + + for guild := range s.client.Caches.Guilds() { + if !isGuildAdmin(s.client, guild, session.UserID) { + continue + } + + var icon string + if guild.Icon != nil { + icon = *guild.Icon + } + guilds = append(guilds, &heimdallrv1.Guild{ + Id: guild.ID.String(), + Name: guild.Name, + Icon: icon, + }) + } + + slog.Debug("ListGuilds", "user_id", session.UserID, "count", len(guilds)) + + return &heimdallrv1.ListGuildsResponse{ + Guilds: guilds, + }, nil +} + +func (s *authService) Logout(ctx context.Context, _ *heimdallrv1.LogoutRequest) (*heimdallrv1.LogoutResponse, error) { + session := SessionFromContext(ctx) + if session == nil { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + if err := model.DeleteSession(session.Token); err != nil { + slog.Error("failed to delete session", "error", err) + } + + // Clear the session cookie. + SetResponseCookie(ctx, makeSessionCookie("", 0)) + + return &heimdallrv1.LogoutResponse{}, nil +} + +// makeSessionCookie creates a session cookie with the given token and max age. +// A maxAge of 0 clears the cookie. +func makeSessionCookie(token string, maxAge int) *http.Cookie { + secure := strings.HasPrefix(viper.GetString("dashboard.base_url"), "https") + return &http.Cookie{ + Name: sessionCookieName, + Value: token, + Path: "/", + MaxAge: maxAge, + HttpOnly: true, + Secure: secure, + SameSite: http.SameSiteStrictMode, + } +} diff --git a/heimdallr/rpcserver/frontend.go b/heimdallr/rpcserver/frontend.go new file mode 100644 index 0000000..6a10353 --- /dev/null +++ b/heimdallr/rpcserver/frontend.go @@ -0,0 +1,50 @@ +//go:build web + +package rpcserver + +import ( + "embed" + "io/fs" + "net/http" + "strings" +) + +//go:embed all:frontend +var frontendFS embed.FS + +// spaHandler serves the embedded frontend files, falling back to index.html +// for any path that doesn't match a real file (SPA client-side routing). +type spaHandler struct { + fs http.Handler + root fs.FS +} + +func newSPAHandler() *spaHandler { + sub, _ := fs.Sub(frontendFS, "frontend") + return &spaHandler{ + fs: http.FileServerFS(sub), + root: sub, + } +} + +func (h *spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Try to serve the requested file. + path := strings.TrimPrefix(r.URL.Path, "/") + if path == "" { + path = "index.html" + } + + // Check if the file exists in the embedded FS. + if _, err := fs.Stat(h.root, path); err == nil { + // Set long cache for hashed assets. + if strings.HasPrefix(path, "assets/") { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } + h.fs.ServeHTTP(w, r) + return + } + + // File not found — serve index.html for SPA fallback. + r.URL.Path = "/" + h.fs.ServeHTTP(w, r) +} diff --git a/heimdallr/rpcserver/frontend/assets/index-DVD23vIT.js b/heimdallr/rpcserver/frontend/assets/index-DVD23vIT.js new file mode 100644 index 0000000..253942e --- /dev/null +++ b/heimdallr/rpcserver/frontend/assets/index-DVD23vIT.js @@ -0,0 +1,6 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))r(a);new MutationObserver(a=>{for(const s of a)if(s.type==="childList")for(const i of s.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(a){const s={};return a.integrity&&(s.integrity=a.integrity),a.referrerPolicy&&(s.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?s.credentials="include":a.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(a){if(a.ep)return;a.ep=!0;const s=n(a);fetch(a.href,s)}})();const Dr=!1;var vn=Array.isArray,Xl=Array.prototype.indexOf,Lt=Array.prototype.includes,or=Array.from,vi=Object.defineProperty,rt=Object.getOwnPropertyDescriptor,gi=Object.getOwnPropertyDescriptors,Jl=Object.prototype,Kl=Array.prototype,sa=Object.getPrototypeOf,Ba=Object.isExtensible;function zt(e){return typeof e=="function"}const Ye=()=>{};function jl(e){return e()}function Pn(e){for(var t=0;t{e=r,t=a});return{promise:n,resolve:e,reject:t}}const de=2,on=4,gn=8,yi=1<<24,tt=16,Me=32,St=64,_i=128,Re=512,oe=1024,me=2048,Ve=4096,we=8192,Qe=16384,hn=32768,ot=65536,Pa=1<<17,Ei=1<<18,Bt=1<<19,Ni=1<<20,He=1<<25,Et=65536,Wr=1<<21,ia=1<<22,at=1<<23,Be=Symbol("$state"),wi=Symbol("legacy props"),zl=Symbol(""),vt=new class extends Error{name="StaleReactionError";message="The reaction that called `getAbortSignal()` was re-run or destroyed"},Hl=globalThis.document?.contentType?.includes("xml")??!1;function lr(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function $l(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function Ql(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function ql(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function eu(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function tu(e){throw new Error("https://svelte.dev/e/effect_orphan")}function nu(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function ru(e){throw new Error("https://svelte.dev/e/lifecycle_legacy_only")}function au(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function su(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function iu(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function ou(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function lu(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const uu=1,cu=2,Ii=4,fu=8,du=16,mu=1,pu=2,bu=4,vu=8,gu=16,hu=1,yu=2,fe=Symbol(),xi="http://www.w3.org/1999/xhtml";function _u(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Eu(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function Si(e){return e===this.v}function Ti(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function Ai(e){return!Ti(e,this.v)}let Pt=!1,Nu=!1;function wu(){Pt=!0}let K=null;function Ft(e){K=e}function Y(e,t=!1,n){K={p:K,i:!1,c:null,e:null,s:e,x:null,l:Pt&&!t?{s:null,u:null,$:[]}:null}}function B(e){var t=K,n=t.e;if(n!==null){t.e=null;for(var r of n)Ji(r)}return t.i=!0,K=t.p,{}}function yn(){return!Pt||K!==null&&K.l===null}let gt=[];function ki(){var e=gt;gt=[],Pn(e)}function qe(e){if(gt.length===0&&!tn){var t=gt;queueMicrotask(()=>{t===gt&&ki()})}gt.push(e)}function Iu(){for(;gt.length>0;)ki()}function Ri(e){var t=X;if(t===null)return W.f|=at,e;if((t.f&hn)===0&&(t.f&on)===0)throw e;Ut(e,t)}function Ut(e,t){for(;t!==null;){if((t.f&_i)!==0){if((t.f&hn)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const xu=-7169;function Q(e,t){e.f=e.f&xu|t}function oa(e){(e.f&Re)!==0||e.deps===null?Q(e,oe):Q(e,Ve)}function Oi(e){if(e!==null)for(const t of e)(t.f&de)===0||(t.f&Et)===0||(t.f^=Et,Oi(t.deps))}function Vi(e,t,n){(e.f&me)!==0?t.add(e):(e.f&Ve)!==0&&n.add(e),Oi(e.deps),Q(e,oe)}const Tn=new Set;let C=null,Xn=null,De=null,ge=[],ur=null,Zr=!1,tn=!1;class st{committed=!1;current=new Map;previous=new Map;#t=new Set;#o=new Set;#e=0;#s=0;#i=null;#r=new Set;#n=new Set;#a=new Map;is_fork=!1;#l=!1;is_deferred(){return this.is_fork||this.#s>0}skip_effect(t){this.#a.has(t)||this.#a.set(t,{d:[],m:[]})}unskip_effect(t){var n=this.#a.get(t);if(n){this.#a.delete(t);for(var r of n.d)Q(r,me),We(r);for(r of n.m)Q(r,Ve),We(r)}}process(t){ge=[],this.apply();var n=[],r=[];for(const a of t)this.#u(a,n,r);if(this.is_deferred()){this.#c(r),this.#c(n);for(const[a,s]of this.#a)Ui(a,s)}else{for(const a of this.#t)a();this.#t.clear(),this.#e===0&&this.#f(),Xn=this,C=null,Xa(r),Xa(n),Xn=null,this.#i?.resolve()}De=null}#u(t,n,r){t.f^=oe;for(var a=t.first,s=null;a!==null;){var i=a.f,o=(i&(Me|St))!==0,l=o&&(i&oe)!==0,u=l||(i&we)!==0||this.#a.has(a);if(!u&&a.fn!==null){o?a.f^=oe:s!==null&&(i&(on|gn|yi))!==0?s.b.defer_effect(a):(i&on)!==0?n.push(a):Jt(a)&&((i&tt)!==0&&this.#n.add(a),It(a));var c=a.first;if(c!==null){a=c;continue}}var m=a.parent;for(a=a.next;a===null&&m!==null;)m===s&&(s=null),a=m.next,m=m.parent}}#c(t){for(var n=0;n0){if(Gi(),C!==null&&C!==this)return}else this.#e===0&&this.process([]);this.deactivate()}discard(){for(const t of this.#o)t(this);this.#o.clear()}#f(){if(Tn.size>1){this.previous.clear();var t=De,n=!0;for(const a of Tn){if(a===this){n=!1;continue}const s=[];for(const[o,l]of this.current){if(a.current.has(o))if(n&&l!==a.current.get(o))a.current.set(o,l);else continue;s.push(o)}if(s.length===0)continue;const i=[...a.current.keys()].filter(o=>!this.current.has(o));if(i.length>0){var r=ge;ge=[];const o=new Set,l=new Map;for(const u of s)Li(u,i,o,l);if(ge.length>0){C=a,a.apply();for(const u of ge)a.#u(u,[],[]);a.deactivate()}ge=r}}C=null,De=t}this.committed=!0,Tn.delete(this)}increment(t){this.#e+=1,t&&(this.#s+=1)}decrement(t){this.#e-=1,t&&(this.#s-=1),!this.#l&&(this.#l=!0,qe(()=>{this.#l=!1,this.is_deferred()?ge.length>0&&this.flush():this.revive()}))}revive(){for(const t of this.#r)this.#n.delete(t),Q(t,me),We(t);for(const t of this.#n)Q(t,Ve),We(t);this.flush()}oncommit(t){this.#t.add(t)}ondiscard(t){this.#o.add(t)}settled(){return(this.#i??=hi()).promise}static ensure(){if(C===null){const t=C=new st;Tn.add(C),tn||qe(()=>{C===t&&t.flush()})}return C}apply(){}}function Su(e){var t=tn;tn=!0;try{for(var n;;){if(Iu(),ge.length===0&&(C?.flush(),ge.length===0))return ur=null,n;Gi()}}finally{tn=t}}function Gi(){Zr=!0;var e=null;try{for(var t=0;ge.length>0;){var n=st.ensure();if(t++>1e3){var r,a;Tu()}n.process(ge),it.clear()}}finally{ge=[],Zr=!1,ur=null}}function Tu(){try{nu()}catch(e){Ut(e,ur)}}let je=null;function Xa(e){var t=e.length;if(t!==0){for(var n=0;n0)){it.clear();for(const a of je){if((a.f&(Qe|we))!==0)continue;const s=[a];let i=a.parent;for(;i!==null;)je.has(i)&&(je.delete(i),s.push(i)),i=i.parent;for(let o=s.length-1;o>=0;o--){const l=s[o];(l.f&(Qe|we))===0&&It(l)}}je.clear()}}je=null}}function Li(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const a of e.reactions){const s=a.f;(s&de)!==0?Li(a,t,n,r):(s&(ia|tt))!==0&&(s&me)===0&&Fi(a,t,r)&&(Q(a,me),We(a))}}function Fi(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const a of e.deps){if(Lt.call(t,a))return!0;if((a.f&de)!==0&&Fi(a,t,n))return n.set(a,!0),!0}return n.set(e,!1),!1}function We(e){for(var t=ur=e;t.parent!==null;){t=t.parent;var n=t.f;if(Zr&&t===X&&(n&tt)!==0&&(n&Ei)===0)return;if((n&(St|Me))!==0){if((n&oe)===0)return;t.f^=oe}}ge.push(t)}function Ui(e,t){if(!((e.f&Me)!==0&&(e.f&oe)!==0)){(e.f&me)!==0?t.d.push(e):(e.f&Ve)!==0&&t.m.push(e),Q(e,oe);for(var n=e.first;n!==null;)Ui(n,t),n=n.next}}function Au(e){let t=0,n=Nt(0),r;return()=>{fa()&&(d(n),Xt(()=>(t===0&&(r=Je(()=>e(()=>rn(n)))),t+=1,()=>{qe(()=>{t-=1,t===0&&(r?.(),r=void 0,rn(n))})})))}}var ku=ot|Bt|_i;function Ru(e,t,n){new Ou(e,t,n)}class Ou{parent;is_pending=!1;#t;#o=null;#e;#s;#i;#r=null;#n=null;#a=null;#l=null;#u=null;#c=0;#f=0;#p=!1;#m=!1;#b=new Set;#v=new Set;#d=null;#E=Au(()=>(this.#d=Nt(this.#c),()=>{this.#d=null}));constructor(t,n,r){this.#t=t,this.#e=n,this.#s=r,this.parent=X.b,this.is_pending=!!this.#e.pending,this.#i=Nn(()=>{X.b=this;{var a=this.#y();try{this.#r=ke(()=>r(a))}catch(s){this.error(s)}this.#f>0?this.#h():this.is_pending=!1}return()=>{this.#u?.remove()}},ku)}#N(){try{this.#r=ke(()=>this.#s(this.#t))}catch(t){this.error(t)}}#w(){const t=this.#e.pending;t&&(this.#n=ke(()=>t(this.#t)),qe(()=>{var n=this.#y();this.#r=this.#g(()=>(st.ensure(),ke(()=>this.#s(n)))),this.#f>0?this.#h():(yt(this.#n,()=>{this.#n=null}),this.is_pending=!1)}))}#y(){var t=this.#t;return this.is_pending&&(this.#u=et(),this.#t.before(this.#u),t=this.#u),t}defer_effect(t){Vi(t,this.#b,this.#v)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#e.pending}#g(t){var n=X,r=W,a=K;Pe(this.#i),Ge(this.#i),Ft(this.#i.ctx);try{return t()}catch(s){return Ri(s),null}finally{Pe(n),Ge(r),Ft(a)}}#h(){const t=this.#e.pending;this.#r!==null&&(this.#l=document.createDocumentFragment(),this.#l.append(this.#u),Qi(this.#r,this.#l)),this.#n===null&&(this.#n=ke(()=>t(this.#t)))}#_(t){if(!this.has_pending_snippet()){this.parent&&this.parent.#_(t);return}if(this.#f+=t,this.#f===0){this.is_pending=!1;for(const n of this.#b)Q(n,me),We(n);for(const n of this.#v)Q(n,Ve),We(n);this.#b.clear(),this.#v.clear(),this.#n&&yt(this.#n,()=>{this.#n=null}),this.#l&&(this.#t.before(this.#l),this.#l=null)}}update_pending_count(t){this.#_(t),this.#c+=t,!(!this.#d||this.#p)&&(this.#p=!0,qe(()=>{this.#p=!1,this.#d&&Dt(this.#d,this.#c)}))}get_effect_pending(){return this.#E(),d(this.#d)}error(t){var n=this.#e.onerror;let r=this.#e.failed;if(this.#m||!n&&!r)throw t;this.#r&&(ye(this.#r),this.#r=null),this.#n&&(ye(this.#n),this.#n=null),this.#a&&(ye(this.#a),this.#a=null);var a=!1,s=!1;const i=()=>{if(a){Eu();return}a=!0,s&&lu(),st.ensure(),this.#c=0,this.#a!==null&&yt(this.#a,()=>{this.#a=null}),this.is_pending=this.has_pending_snippet(),this.#r=this.#g(()=>(this.#m=!1,ke(()=>this.#s(this.#t)))),this.#f>0?this.#h():this.is_pending=!1};qe(()=>{try{s=!0,n?.(t,i),s=!1}catch(o){Ut(o,this.#i&&this.#i.parent)}r&&(this.#a=this.#g(()=>{st.ensure(),this.#m=!0;try{return ke(()=>{r(this.#t,()=>t,()=>i)})}catch(o){return Ut(o,this.#i.parent),null}finally{this.#m=!1}}))})}}function Vu(e,t,n,r){const a=yn()?_n:la;var s=e.filter(p=>!p.settled);if(n.length===0&&s.length===0){r(t.map(a));return}var i=C,o=X,l=Gu(),u=s.length===1?s[0].promise:s.length>1?Promise.all(s.map(p=>p.promise)):null;function c(p){l();try{r(p)}catch(f){(o.f&Qe)===0&&Ut(f,o)}i?.deactivate(),Cr()}if(n.length===0){u.then(()=>c(t.map(a)));return}function m(){l(),Promise.all(n.map(p=>Lu(p))).then(p=>c([...t.map(a),...p])).catch(p=>Ut(p,o))}u?u.then(m):m()}function Gu(){var e=X,t=W,n=K,r=C;return function(s=!0){Pe(e),Ge(t),Ft(n),s&&r?.activate()}}function Cr(){Pe(null),Ge(null),Ft(null)}function _n(e){var t=de|me,n=W!==null&&(W.f&de)!==0?W:null;return X!==null&&(X.f|=Bt),{ctx:K,deps:null,effects:null,equals:Si,f:t,fn:e,reactions:null,rv:0,v:fe,wv:0,parent:n??X,ac:null}}function Lu(e,t,n){let r=X;r===null&&$l();var a=r.b,s=void 0,i=Nt(fe),o=!W,l=new Map;return zu(()=>{var u=hi();s=u.promise;try{Promise.resolve(e()).then(u.resolve,u.reject).then(()=>{c===C&&c.committed&&c.deactivate(),Cr()})}catch(f){u.reject(f),Cr()}var c=C;if(o){var m=a.is_rendered();a.update_pending_count(1),c.increment(m),l.get(c)?.reject(vt),l.delete(c),l.set(c,u)}const p=(f,b=void 0)=>{if(c.activate(),b)b!==vt&&(i.f|=at,Dt(i,b));else{(i.f&at)!==0&&(i.f^=at),Dt(i,f);for(const[h,v]of l){if(l.delete(h),h===c)break;v.reject(vt)}}o&&(a.update_pending_count(-1),c.decrement(m))};u.promise.then(p,f=>p(null,f||"unknown"))}),fr(()=>{for(const u of l.values())u.reject(vt)}),new Promise(u=>{function c(m){function p(){m===s?u(i):c(s)}m.then(p,p)}c(s)})}function ae(e){const t=_n(e);return qi(t),t}function la(e){const t=_n(e);return t.equals=Ai,t}function Fu(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n0&&!Zi&&Wu()}return t}function Wu(){Zi=!1;for(const e of Mr)(e.f&oe)!==0&&Q(e,Ve),Jt(e)&&It(e);Mr.clear()}function rn(e){F(e,e.v+1)}function Ci(e,t){var n=e.reactions;if(n!==null)for(var r=yn(),a=n.length,s=0;s{if(_t===s)return o();var l=W,u=_t;Ge(null),Ha(s);var c=o();return Ge(l),Ha(u),c};return r&&n.set("length",j(e.length)),new Proxy(e,{defineProperty(o,l,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&su();var c=n.get(l);return c===void 0?i(()=>{var m=j(u.value);return n.set(l,m),m}):F(c,u.value,!0),!0},deleteProperty(o,l){var u=n.get(l);if(u===void 0){if(l in o){const c=i(()=>j(fe));n.set(l,c),rn(a)}}else F(u,fe),rn(a);return!0},get(o,l,u){if(l===Be)return e;var c=n.get(l),m=l in o;if(c===void 0&&(!m||rt(o,l)?.writable)&&(c=i(()=>{var f=ie(m?o[l]:fe),b=j(f);return b}),n.set(l,c)),c!==void 0){var p=d(c);return p===fe?void 0:p}return Reflect.get(o,l,u)},getOwnPropertyDescriptor(o,l){var u=Reflect.getOwnPropertyDescriptor(o,l);if(u&&"value"in u){var c=n.get(l);c&&(u.value=d(c))}else if(u===void 0){var m=n.get(l),p=m?.v;if(m!==void 0&&p!==fe)return{enumerable:!0,configurable:!0,value:p,writable:!0}}return u},has(o,l){if(l===Be)return!0;var u=n.get(l),c=u!==void 0&&u.v!==fe||Reflect.has(o,l);if(u!==void 0||X!==null&&(!c||rt(o,l)?.writable)){u===void 0&&(u=i(()=>{var p=c?ie(o[l]):fe,f=j(p);return f}),n.set(l,u));var m=d(u);if(m===fe)return!1}return c},set(o,l,u,c){var m=n.get(l),p=l in o;if(r&&l==="length")for(var f=u;fj(fe)),n.set(f+"",b))}if(m===void 0)(!p||rt(o,l)?.writable)&&(m=i(()=>j(void 0)),F(m,ie(u)),n.set(l,m));else{p=m.v!==fe;var h=i(()=>ie(u));F(m,h)}var v=Reflect.getOwnPropertyDescriptor(o,l);if(v?.set&&v.set.call(c,u),!p){if(r&&typeof l=="string"){var N=n.get("length"),O=Number(l);Number.isInteger(O)&&O>=N.v&&F(N,O+1)}rn(a)}return!0},ownKeys(o){d(a);var l=Reflect.ownKeys(o).filter(m=>{var p=n.get(m);return p===void 0||p.v!==fe});for(var[u,c]of n)c.v!==fe&&!(u in o)&&l.push(u);return l},setPrototypeOf(){iu()}})}function Ja(e){try{if(e!==null&&typeof e=="object"&&Be in e)return e[Be]}catch{}return e}function Zu(e,t){return Object.is(Ja(e),Ja(t))}var Ka,Mi,Yi,Bi;function Cu(){if(Ka===void 0){Ka=window,Mi=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Yi=rt(t,"firstChild").get,Bi=rt(t,"nextSibling").get,Ba(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),Ba(n)&&(n.__t=void 0)}}function et(e=""){return document.createTextNode(e)}function Jn(e){return Yi.call(e)}function En(e){return Bi.call(e)}function y(e,t){return Jn(e)}function q(e,t=!1){{var n=Jn(e);return n instanceof Comment&&n.data===""?En(n):n}}function I(e,t=1,n=!1){let r=e;for(;t--;)r=En(r);return r}function Mu(e){e.textContent=""}function Pi(){return!1}function Yu(e,t,n){return document.createElementNS(xi,e,void 0)}let ja=!1;function Bu(){ja||(ja=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(const t of e.target.elements)t.__on_r?.()})},{capture:!0}))}function cr(e){var t=W,n=X;Ge(null),Pe(null);try{return e()}finally{Ge(t),Pe(n)}}function ca(e,t,n,r=n){e.addEventListener(t,()=>cr(n));const a=e.__on_r;a?e.__on_r=()=>{a(),r(!0)}:e.__on_r=()=>r(!0),Bu()}function Xi(e){X===null&&(W===null&&tu(),eu()),lt&&ql()}function Pu(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Xe(e,t,n){var r=X;r!==null&&(r.f&we)!==0&&(e|=we);var a={ctx:K,deps:null,nodes:null,f:e|me|Re,first:null,fn:t,last:null,next:null,parent:r,b:r&&r.b,prev:null,teardown:null,wv:0,ac:null};if(n)try{It(a)}catch(o){throw ye(a),o}else t!==null&&We(a);var s=a;if(n&&s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&Bt)===0&&(s=s.first,(e&tt)!==0&&(e&ot)!==0&&s!==null&&(s.f|=ot)),s!==null&&(s.parent=r,r!==null&&Pu(s,r),W!==null&&(W.f&de)!==0&&(e&St)===0)){var i=W;(i.effects??=[]).push(s)}return a}function fa(){return W!==null&&!Ze}function fr(e){const t=Xe(gn,null,!1);return Q(t,oe),t.teardown=e,t}function wt(e){Xi();var t=X.f,n=!W&&(t&Me)!==0&&(t&hn)===0;if(n){var r=K;(r.e??=[]).push(e)}else return Ji(e)}function Ji(e){return Xe(on|Ni,e,!1)}function Xu(e){return Xi(),Xe(gn|Ni,e,!0)}function Ju(e){st.ensure();const t=Xe(St|Bt,e,!0);return(n={})=>new Promise(r=>{n.outro?yt(t,()=>{ye(t),r(void 0)}):(ye(t),r(void 0))})}function Ki(e){return Xe(on,e,!1)}function Ku(e,t){var n=K,r={effect:null,ran:!1,deps:e};n.l.$.push(r),r.effect=Xt(()=>{e(),!r.ran&&(r.ran=!0,Je(t))})}function ju(){var e=K;Xt(()=>{for(var t of e.l.$){t.deps();var n=t.effect;(n.f&oe)!==0&&n.deps!==null&&Q(n,Ve),Jt(n)&&It(n),t.ran=!1}})}function zu(e){return Xe(ia|Bt,e,!0)}function Xt(e,t=0){return Xe(gn|t,e,!0)}function G(e,t=[],n=[],r=[]){Vu(r,t,n,a=>{Xe(gn,()=>e(...a.map(d)),!0)})}function Nn(e,t=0){var n=Xe(tt|t,e,!0);return n}function ke(e){return Xe(Me|Bt,e,!0)}function ji(e){var t=e.teardown;if(t!==null){const n=lt,r=W;za(!0),Ge(null);try{t.call(null)}finally{za(n),Ge(r)}}}function da(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const a=n.ac;a!==null&&cr(()=>{a.abort(vt)});var r=n.next;(n.f&St)!==0?n.parent=null:ye(n,t),n=r}}function Hu(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&Me)===0&&ye(t),t=n}}function ye(e,t=!0){var n=!1;(t||(e.f&Ei)!==0)&&e.nodes!==null&&e.nodes.end!==null&&($u(e.nodes.start,e.nodes.end),n=!0),da(e,t&&!n),ln(e,0),Q(e,Qe);var r=e.nodes&&e.nodes.t;if(r!==null)for(const s of r)s.stop();ji(e);var a=e.parent;a!==null&&a.first!==null&&zi(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function $u(e,t){for(;e!==null;){var n=e===t?null:En(e);e.remove(),e=n}}function zi(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function yt(e,t,n=!0){var r=[];Hi(e,r,!0);var a=()=>{n&&ye(e),t&&t()},s=r.length;if(s>0){var i=()=>--s||a();for(var o of r)o.out(i)}else a()}function Hi(e,t,n){if((e.f&we)===0){e.f^=we;var r=e.nodes&&e.nodes.t;if(r!==null)for(const o of r)(o.is_global||n)&&t.push(o);for(var a=e.first;a!==null;){var s=a.next,i=(a.f&ot)!==0||(a.f&Me)!==0&&(e.f&tt)!==0;Hi(a,t,i?n:!1),a=s}}}function ma(e){$i(e,!0)}function $i(e,t){if((e.f&we)!==0){e.f^=we,(e.f&oe)===0&&(Q(e,me),We(e));for(var n=e.first;n!==null;){var r=n.next,a=(n.f&ot)!==0||(n.f&Me)!==0;$i(n,a?t:!1),n=r}var s=e.nodes&&e.nodes.t;if(s!==null)for(const i of s)(i.is_global||t)&&i.in()}}function Qi(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var a=n===r?null:En(n);t.append(n),n=a}}let Cn=!1,lt=!1;function za(e){lt=e}let W=null,Ze=!1;function Ge(e){W=e}let X=null;function Pe(e){X=e}let Oe=null;function qi(e){W!==null&&(Oe===null?Oe=[e]:Oe.push(e))}let he=null,Ee=0,Ae=null;function Qu(e){Ae=e}let eo=1,ht=0,_t=ht;function Ha(e){_t=e}function to(){return++eo}function Jt(e){var t=e.f;if((t&me)!==0)return!0;if(t&de&&(e.f&=~Et),(t&Ve)!==0){for(var n=e.deps,r=n.length,a=0;ae.wv)return!0}(t&Re)!==0&&De===null&&Q(e,oe)}return!1}function no(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Oe!==null&&Lt.call(Oe,e)))for(var a=0;a{e.ac.abort(vt)}),e.ac=null);try{e.f|=Wr;var c=e.fn,m=c();e.f|=hn;var p=e.deps,f=C?.is_fork;if(he!==null){var b;if(f||ln(e,Ee),p!==null&&Ee>0)for(p.length=Ee+he.length,b=0;bn?.call(this,s))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?qe(()=>{t.addEventListener(e,a,r)}):t.addEventListener(e,a,r),a}function $a(e,t,n,r,a){var s={capture:r,passive:a},i=nc(e,t,n,s);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&fr(()=>{t.removeEventListener(e,i,s)})}function P(e,t,n){(t[oo]??={})[e]=n}function ve(e){for(var t=0;t{throw v});throw p}}finally{e.__root=t,delete e.currentTarget,Ge(c),Pe(m)}}}const rc=globalThis?.window?.trustedTypes?.createPolicy("svelte-trusted-html",{createHTML:e=>e});function ac(e){return rc?.createHTML(e)??e}function sc(e,t=!1){var n=Yu("template");return e=e.replaceAll("",""),n.innerHTML=t?ac(e):e,n.content}function Kn(e,t){var n=X;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function x(e,t){var n=(t&hu)!==0,r=(t&yu)!==0,a,s=!e.startsWith("");return()=>{a===void 0&&(a=sc(s?e:""+e,!0),n||(a=Jn(a)));var i=r||Mi?document.importNode(a,!0):a.cloneNode(!0);if(n){var o=Jn(i),l=i.lastChild;Kn(o,l)}else Kn(i,i);return i}}function ic(e=""){{var t=et(e+"");return Kn(t,t),t}}function Ce(){var e=document.createDocumentFragment(),t=document.createComment(""),n=et();return e.append(t,n),Kn(t,n),e}function E(e,t){e!==null&&e.before(t)}function D(e,t){var n=t==null?"":typeof t=="object"?t+"":t;n!==(e.__t??=e.nodeValue)&&(e.__t=n,e.nodeValue=n+"")}function oc(e,t){return lc(e,t)}const An=new Map;function lc(e,{target:t,anchor:n,props:r={},events:a,context:s,intro:i=!0}){Cu();var o=new Set,l=m=>{for(var p=0;p{var m=n??t.appendChild(et());return Ru(m,{pending:()=>{}},p=>{Y({});var f=K;s&&(f.c=s),a&&(r.$$events=a),u=e(p,r)||{},B()}),()=>{for(var p of o)for(const h of[t,document]){var f=An.get(h),b=f.get(p);--b==0?(h.removeEventListener(p,Pr),f.delete(p),f.size===0&&An.delete(h)):f.set(p,b)}Br.delete(l),m!==n&&m.parentNode?.removeChild(m)}});return uc.set(u,c),u}let uc=new WeakMap;class ba{anchor;#t=new Map;#o=new Map;#e=new Map;#s=new Set;#i=!0;constructor(t,n=!0){this.anchor=t,this.#i=n}#r=()=>{var t=C;if(this.#t.has(t)){var n=this.#t.get(t),r=this.#o.get(n);if(r)ma(r),this.#s.delete(n);else{var a=this.#e.get(n);a&&(this.#o.set(n,a.effect),this.#e.delete(n),a.fragment.lastChild.remove(),this.anchor.before(a.fragment),r=a.effect)}for(const[s,i]of this.#t){if(this.#t.delete(s),s===t)break;const o=this.#e.get(i);o&&(ye(o.effect),this.#e.delete(i))}for(const[s,i]of this.#o){if(s===n||this.#s.has(s))continue;const o=()=>{if(Array.from(this.#t.values()).includes(s)){var u=document.createDocumentFragment();Qi(i,u),u.append(et()),this.#e.set(s,{effect:i,fragment:u})}else ye(i);this.#s.delete(s),this.#o.delete(s)};this.#i||!r?(this.#s.add(s),yt(i,o,!1)):o()}}};#n=t=>{this.#t.delete(t);const n=Array.from(this.#t.values());for(const[r,a]of this.#e)n.includes(r)||(ye(a.effect),this.#e.delete(r))};ensure(t,n){var r=C,a=Pi();if(n&&!this.#o.has(t)&&!this.#e.has(t))if(a){var s=document.createDocumentFragment(),i=et();s.append(i),this.#e.set(t,{effect:ke(()=>n(i)),fragment:s})}else this.#o.set(t,ke(()=>n(this.anchor)));if(this.#t.set(r,t),a){for(const[o,l]of this.#o)o===t?r.unskip_effect(l):r.skip_effect(l);for(const[o,l]of this.#e)o===t?r.unskip_effect(l.effect):r.skip_effect(l.effect);r.oncommit(this.#r),r.ondiscard(this.#n)}else this.#r()}}function L(e,t,n=!1){var r=new ba(e),a=n?ot:0;function s(i,o){r.ensure(i,o)}Nn(()=>{var i=!1;t((o,l=0)=>{i=!0,s(l,o)}),i||s(!1,null)},a)}function te(e,t){return t}function cc(e,t,n){for(var r=[],a=t.length,s,i=t.length,o=0;o{if(s){if(s.pending.delete(m),s.done.add(m),s.pending.size===0){var p=e.outrogroups;Xr(or(s.done)),p.delete(s),p.size===0&&(e.outrogroups=null)}}else i-=1},!1)}if(i===0){var l=r.length===0&&n!==null;if(l){var u=n,c=u.parentNode;Mu(c),c.append(u),e.items.clear()}Xr(t,!l)}else s={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(s)}function Xr(e,t=!0){for(var n=0;n{var N=n();return vn(N)?N:N==null?[]:or(N)}),p,f=!0;function b(){v.fallback=c,fc(v,p,i,t,r),c!==null&&(p.length===0?(c.f&He)===0?ma(c):(c.f^=He,Qt(c,null,i)):yt(c,()=>{c=null}))}var h=Nn(()=>{p=d(m);for(var N=p.length,O=new Set,T=C,_=Pi(),w=0;ws(i)):(c=ke(()=>s(qa??=et())),c.f|=He)),N>O.size&&Ql(),!f)if(_){for(const[R,V]of o)O.has(R)||T.skip_effect(V.e);T.oncommit(b),T.ondiscard(()=>{})}else b();d(m)}),v={effect:h,items:o,outrogroups:null,fallback:c};f=!1}function Ht(e){for(;e!==null&&(e.f&Me)===0;)e=e.next;return e}function fc(e,t,n,r,a){var s=(r&fu)!==0,i=t.length,o=e.items,l=Ht(e.effect.first),u,c=null,m,p=[],f=[],b,h,v,N;if(s)for(N=0;N0){var R=(r&Ii)!==0&&i===0?n:null;if(s){for(N=0;N{if(m!==void 0)for(v of m)v.nodes?.a?.apply()})}function dc(e,t,n,r,a,s,i,o){var l=(i&uu)!==0?(i&du)===0?nn(n,!1,!1):Nt(n):null,u=(i&cu)!==0?Nt(a):null;return{v:l,i:u,e:ke(()=>(s(t,l??n,u??a,o),()=>{e.delete(r)}))}}function Qt(e,t,n){if(e.nodes)for(var r=e.nodes.start,a=e.nodes.end,s=t&&(t.f&He)===0?t.nodes.start:n;r!==null;){var i=En(r);if(s.before(r),r===a)return;r=i}}function nt(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function mc(e,t,...n){var r=new ba(e);Nn(()=>{const a=t()??null;r.ensure(a,a&&(s=>a(s,...n)))},ot)}function Jr(e,t,n){var r=new ba(e);Nn(()=>{var a=t()??null;r.ensure(a,a&&(s=>n(s,a)))},ot)}function uo(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(t=0;t=0;){var o=i+s;(i===0||ts.includes(r[i-1]))&&(o===r.length||ts.includes(r[o]))?r=(i===0?"":r.substring(0,i))+r.substring(o+1):i=o}}return r===""?null:r}function ns(e,t=!1){var n=t?" !important;":";",r="";for(var a in e){var s=e[a];s!=null&&s!==""&&(r+=" "+a+": "+s+n)}return r}function vc(e,t){if(t){var n="",r,a;return Array.isArray(t)?(r=t[0],a=t[1]):r=t,r&&(n+=ns(r)),a&&(n+=ns(a,!0)),n=n.trim(),n===""?null:n}return String(e)}function Gt(e,t,n,r,a,s){var i=e.__className;if(i!==n||i===void 0){var o=bc(n,r,s);o==null?e.removeAttribute("class"):e.className=o,e.__className=n}else if(s&&a!==s)for(var l in s){var u=!!s[l];(a==null||u!==!!a[l])&&e.classList.toggle(l,u)}return s}function wr(e,t={},n,r){for(var a in n){var s=n[a];t[a]!==s&&(n[a]==null?e.style.removeProperty(a):e.style.setProperty(a,s,r))}}function gc(e,t,n,r){var a=e.__style;if(a!==t){var s=vc(t,r);s==null?e.removeAttribute("style"):e.style.cssText=s,e.__style=t}else r&&(Array.isArray(r)?(wr(e,n?.[0],r[0]),wr(e,n?.[1],r[1],"important")):wr(e,n,r));return r}function wn(e,t,n=!1){if(e.multiple){if(t==null)return;if(!vn(t))return _u();for(var r of e.options)r.selected=t.includes(an(r));return}for(r of e.options){var a=an(r);if(Zu(a,t)){r.selected=!0;return}}(!n||t!==void 0)&&(e.selectedIndex=-1)}function dr(e){var t=new MutationObserver(()=>{wn(e,e.__value)});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),fr(()=>{t.disconnect()})}function co(e,t,n=t){var r=new WeakSet,a=!0;ca(e,"change",s=>{var i=s?"[selected]":":checked",o;if(e.multiple)o=[].map.call(e.querySelectorAll(i),an);else{var l=e.querySelector(i)??e.querySelector("option:not([disabled])");o=l&&an(l)}n(o),C!==null&&r.add(C)}),Ki(()=>{var s=t();if(e===document.activeElement){var i=Xn??C;if(r.has(i))return}if(wn(e,s,a),a&&s===void 0){var o=e.querySelector(":checked");o!==null&&(s=an(o),n(s))}e.__value=s,a=!1}),dr(e)}function an(e){return"__value"in e?e.__value:e.value}const hc=Symbol("is custom element"),yc=Symbol("is html"),_c=Hl?"progress":"PROGRESS";function fo(e,t){var n=va(e);n.value===(n.value=t??void 0)||e.value===t&&(t!==0||e.nodeName!==_c)||(e.value=t??"")}function mo(e,t){var n=va(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function pe(e,t,n,r){var a=va(e);a[t]!==(a[t]=n)&&(t==="loading"&&(e[zl]=n),n==null?e.removeAttribute(t):typeof n!="string"&&Ec(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function va(e){return e.__attributes??={[hc]:e.nodeName.includes("-"),[yc]:e.namespaceURI===xi}}var rs=new Map;function Ec(e){var t=e.getAttribute("is")||e.nodeName,n=rs.get(t);if(n)return n;rs.set(t,n=[]);for(var r,a=e,s=Element.prototype;s!==a;){r=gi(a);for(var i in r)r[i].set&&n.push(i);a=sa(a)}return n}function Ne(e,t,n=t){var r=new WeakSet;ca(e,"input",async a=>{var s=a?e.defaultValue:e.value;if(s=Ir(e)?xr(s):s,n(s),C!==null&&r.add(C),await pa(),s!==(s=t())){var i=e.selectionStart,o=e.selectionEnd,l=e.value.length;if(e.value=s??"",o!==null){var u=e.value.length;i===o&&o===l&&u>l?(e.selectionStart=u,e.selectionEnd=u):(e.selectionStart=i,e.selectionEnd=Math.min(o,u))}}}),Je(t)==null&&e.value&&(n(Ir(e)?xr(e.value):e.value),C!==null&&r.add(C)),Xt(()=>{var a=t();if(e===document.activeElement){var s=Xn??C;if(r.has(s))return}Ir(e)&&a===xr(e.value)||e.type==="date"&&!a&&!e.value||a!==e.value&&(e.value=a??"")})}function po(e,t,n=t){ca(e,"change",r=>{var a=r?e.defaultChecked:e.checked;n(a)}),Je(t)==null&&n(e.checked),Xt(()=>{var r=t();e.checked=!!r})}function Ir(e){var t=e.type;return t==="number"||t==="range"}function xr(e){return e===""?null:+e}function as(e,t){return e===t||e?.[Be]===t}function Nc(e={},t,n,r){return Ki(()=>{var a,s;return Xt(()=>{a=s,s=[],Je(()=>{e!==n(...s)&&(t(e,...s),a&&as(n(...a),e)&&t(null,...a))})}),()=>{qe(()=>{s&&as(n(...s),e)&&t(null,...s)})}}),e}function ga(e=!1){const t=K,n=t.l.u;if(!n)return;let r=()=>io(t.s);if(e){let a=0,s={};const i=_n(()=>{let o=!1;const l=t.s;for(const u in l)l[u]!==s[u]&&(s[u]=l[u],o=!0);return o&&a++,a});r=()=>d(i)}n.b.length&&Xu(()=>{ss(t,r),Pn(n.b)}),wt(()=>{const a=Je(()=>n.m.map(jl));return()=>{for(const s of a)typeof s=="function"&&s()}}),n.a.length&&wt(()=>{ss(t,r),Pn(n.a)})}function ss(e,t){if(e.l.s)for(const n of e.l.s)d(n);t()}function is(e,t){var n=e.$$events?.[t.type],r=vn(n)?n.slice():n==null?[]:[n];for(var a of r)a.call(this,t)}function ha(e,t,n){if(e==null)return t(void 0),n&&n(void 0),Ye;const r=Je(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}const Ot=[];function bo(e,t){return{subscribe:vo(e,t).subscribe}}function vo(e,t=Ye){let n=null;const r=new Set;function a(o){if(Ti(e,o)&&(e=o,n)){const l=!Ot.length;for(const u of r)u[1](),Ot.push(u,e);if(l){for(let u=0;u{r.delete(u),r.size===0&&n&&(n(),n=null)}}return{set:a,update:s,subscribe:i}}function go(e,t,n){const r=!Array.isArray(e),a=r?[e]:e;if(!a.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const s=t.length<2;return bo(n,(i,o)=>{let l=!1;const u=[];let c=0,m=Ye;const p=()=>{if(c)return;m();const b=t(r?u[0]:u,i,o);s?i(b):m=typeof b=="function"?b:Ye},f=a.map((b,h)=>ha(b,v=>{u[h]=v,c&=~(1<{c|=1<t=n)(),t}let kn=!1,Kr=Symbol();function Ic(e,t,n){const r=n[t]??={store:null,source:nn(void 0),unsubscribe:Ye};if(r.store!==e&&!(Kr in n))if(r.unsubscribe(),r.store=e??null,e==null)r.source.v=void 0,r.unsubscribe=Ye;else{var a=!0;r.unsubscribe=ha(e,s=>{a?r.source.v=s:F(r.source,s)}),a=!1}return e&&Kr in n?wc(e):d(r.source)}function xc(){const e={};function t(){fr(()=>{for(var n in e)e[n].unsubscribe();vi(e,Kr,{enumerable:!1,value:!0})})}return[e,t]}function Sc(e){var t=kn;try{return kn=!1,[e(),kn]}finally{kn=t}}const Tc={get(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(zt(r)&&(r=r()),typeof r=="object"&&r!==null&&t in r)return r[t]}},set(e,t,n){let r=e.props.length;for(;r--;){let a=e.props[r];zt(a)&&(a=a());const s=rt(a,t);if(s&&s.set)return s.set(n),!0}return!1},getOwnPropertyDescriptor(e,t){let n=e.props.length;for(;n--;){let r=e.props[n];if(zt(r)&&(r=r()),typeof r=="object"&&r!==null&&t in r){const a=rt(r,t);return a&&!a.configurable&&(a.configurable=!0),a}}},has(e,t){if(t===Be||t===wi)return!1;for(let n of e.props)if(zt(n)&&(n=n()),n!=null&&t in n)return!0;return!1},ownKeys(e){const t=[];for(let n of e.props)if(zt(n)&&(n=n()),!!n){for(const r in n)t.includes(r)||t.push(r);for(const r of Object.getOwnPropertySymbols(n))t.includes(r)||t.push(r)}return t}};function os(...e){return new Proxy({props:e},Tc)}function Ie(e,t,n,r){var a=!Pt||(n&pu)!==0,s=(n&vu)!==0,i=(n&gu)!==0,o=r,l=!0,u=()=>(l&&(l=!1,o=i?Je(r):r),o),c;if(s){var m=Be in e||wi in e;c=rt(e,t)?.set??(m&&t in e?T=>e[t]=T:void 0)}var p,f=!1;s?[p,f]=Sc(()=>e[t]):p=e[t],p===void 0&&r!==void 0&&(p=u(),c&&(a&&au(),c(p)));var b;if(a?b=()=>{var T=e[t];return T===void 0?u():(l=!0,T)}:b=()=>{var T=e[t];return T!==void 0&&(o=void 0),T===void 0?o:T},a&&(n&bu)===0)return b;if(c){var h=e.$$legacy;return(function(T,_){return arguments.length>0?((!a||!_||h||f)&&c(_?b():T),T):b()})}var v=!1,N=((n&mu)!==0?_n:la)(()=>(v=!1,b()));s&&d(N);var O=X;return(function(T,_){if(arguments.length>0){const w=_?d(N):a&&s?ie(T):T;return F(N,w),v=!0,o!==void 0&&(o=w),T}return lt&&v||(O.f&Qe)!==0?N.v:d(N)})}function Kt(e){K===null&&lr(),Pt&&K.l!==null?ho(K).m.push(e):wt(()=>{const t=Je(e);if(typeof t=="function")return t})}function Ac(e){K===null&&lr(),Kt(()=>()=>Je(e))}function kc(e,t,{bubbles:n=!1,cancelable:r=!1}={}){return new CustomEvent(e,{detail:t,bubbles:n,cancelable:r})}function Rc(){const e=K;return e===null&&lr(),(t,n,r)=>{const a=e.s.$$events?.[t];if(a){const s=vn(a)?a.slice():[a],i=kc(t,n,r);for(const o of s)o.call(e.x,i);return!i.defaultPrevented}return!0}}function Oc(e){K===null&&lr(),K.l===null&&ru(),ho(K).a.push(e)}function ho(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}const Vc="5";typeof window<"u"&&((window.__svelte??={}).v??=new Set).add(Vc);wu();function Gc(e,t){if(e instanceof RegExp)return{keys:!1,pattern:e};var n,r,a,s,i=[],o="",l=e.split("/");for(l[0]||l.shift();a=l.shift();)n=a[0],n==="*"?(i.push("wild"),o+="/(.*)"):n===":"?(r=a.indexOf("?",1),s=a.indexOf(".",1),i.push(a.substring(1,~r?r:~s?s:a.length)),o+=~r&&!~s?"(?:/([^/]+?))?":"/([^/]+?)",~s&&(o+=(~r?"?":"")+"\\"+a.substring(s))):o+="/"+a;return{keys:i,pattern:new RegExp("^"+o+"/?$","i")}}function ls(){const e=window.location.href.indexOf("#/");let t=e>-1?window.location.href.substr(e+1):"/";const n=t.indexOf("?");let r="";return n>-1&&(r=t.substr(n+1),t=t.substr(0,n)),{location:t,querystring:r}}const ya=bo(null,function(t){t(ls());const n=()=>{t(ls())};return window.addEventListener("hashchange",n,!1),function(){window.removeEventListener("hashchange",n,!1)}});go(ya,e=>e.location);const Lc=go(ya,e=>e.querystring),us=vo(void 0);async function In(e){if(!e||e.length<1||e.charAt(0)!="/"&&e.indexOf("#/")!==0)throw Error("Invalid parameter location");await pa(),history.replaceState({...history.state,__svelte_spa_router_scrollX:window.scrollX,__svelte_spa_router_scrollY:window.scrollY},void 0),window.location.hash=(e.charAt(0)=="#"?"":"#")+e}function Fc(e){e?window.scrollTo(e.__svelte_spa_router_scrollX,e.__svelte_spa_router_scrollY):window.scrollTo(0,0)}function Uc(e,t){Y(t,!1);let n=Ie(t,"routes",24,()=>({})),r=Ie(t,"prefix",8,""),a=Ie(t,"restoreScrollState",8,!1);class s{constructor(A,S){if(!S||typeof S!="function"&&(typeof S!="object"||S._sveltesparouter!==!0))throw Error("Invalid component object");if(!A||typeof A=="string"&&(A.length<1||A.charAt(0)!="/"&&A.charAt(0)!="*")||typeof A=="object"&&!(A instanceof RegExp))throw Error('Invalid value for "path" argument - strings must start with / or *');const{pattern:k,keys:R}=Gc(A);this.path=A,typeof S=="object"&&S._sveltesparouter===!0?(this.component=S.component,this.conditions=S.conditions||[],this.userData=S.userData,this.props=S.props||{}):(this.component=()=>Promise.resolve(S),this.conditions=[],this.props={}),this._pattern=k,this._keys=R}match(A){if(r()){if(typeof r()=="string")if(A.startsWith(r()))A=A.substr(r().length)||"/";else return null;else if(r()instanceof RegExp){const V=A.match(r());if(V&&V[0])A=A.substr(V[0].length)||"/";else return null}}const S=this._pattern.exec(A);if(S===null)return null;if(this._keys===!1)return S;const k={};let R=0;for(;R{i.push(new s(A,w))}):Object.keys(n()).forEach(w=>{i.push(new s(w,n()[w]))});let o=nn(null),l=nn(null),u=nn({});const c=Rc();async function m(w,A){await pa(),c(w,A)}let p=null,f=null;a()&&(f=w=>{w.state&&(w.state.__svelte_spa_router_scrollY||w.state.__svelte_spa_router_scrollX)?p=w.state:p=null},window.addEventListener("popstate",f),Oc(()=>{Fc(p)}));let b=null,h=null;const v=ya.subscribe(async w=>{b=w;let A=0;for(;A{us.set(d(l))});return}F(o,null),h=null,us.set(void 0)});Ac(()=>{v(),f&&window.removeEventListener("popstate",f)}),Ku(()=>io(a()),()=>{history.scrollRestoration=a()?"manual":"auto"}),ju(),ga();var N=Ce(),O=q(N);{var T=w=>{var A=Ce(),S=q(A);Jr(S,()=>d(o),(k,R)=>{R(k,os({get params(){return d(l)}},()=>d(u),{$$events:{routeEvent(V){is.call(this,t,V)}}}))}),E(w,A)},_=w=>{var A=Ce(),S=q(A);Jr(S,()=>d(o),(k,R)=>{R(k,os(()=>d(u),{$$events:{routeEvent(V){is.call(this,t,V)}}}))}),E(w,A)};L(O,w=>{d(l)?w(T):w(_,!1)})}E(e,N),B()}let Sr=j(null);function jt(){return{get user(){return d(Sr)},set user(e){F(Sr,e,!0)},get isLoggedIn(){return d(Sr)!==null}}}var Dc=x(`

Heimdallr

Manage your Discord server settings from the web.

How to log in

Use the /admin-dashboard command in a + Discord server where Heimdallr is installed to get a login link.

`);function Wc(e,t){Y(t,!1);const n=jt();Kt(()=>{n.isLoggedIn&&In("/guilds")}),ga();var r=Dc();E(e,r),B()}var J;(function(e){e[e.Canceled=1]="Canceled",e[e.Unknown=2]="Unknown",e[e.InvalidArgument=3]="InvalidArgument",e[e.DeadlineExceeded=4]="DeadlineExceeded",e[e.NotFound=5]="NotFound",e[e.AlreadyExists=6]="AlreadyExists",e[e.PermissionDenied=7]="PermissionDenied",e[e.ResourceExhausted=8]="ResourceExhausted",e[e.FailedPrecondition=9]="FailedPrecondition",e[e.Aborted=10]="Aborted",e[e.OutOfRange=11]="OutOfRange",e[e.Unimplemented=12]="Unimplemented",e[e.Internal=13]="Internal",e[e.Unavailable=14]="Unavailable",e[e.DataLoss=15]="DataLoss",e[e.Unauthenticated=16]="Unauthenticated"})(J||(J={}));function _a(e,t){return e!==null&&typeof e=="object"&&"$typeName"in e&&typeof e.$typeName=="string"?t===void 0?!0:t.typeName===e.$typeName:!1}var g;(function(e){e[e.DOUBLE=1]="DOUBLE",e[e.FLOAT=2]="FLOAT",e[e.INT64=3]="INT64",e[e.UINT64=4]="UINT64",e[e.INT32=5]="INT32",e[e.FIXED64=6]="FIXED64",e[e.FIXED32=7]="FIXED32",e[e.BOOL=8]="BOOL",e[e.STRING=9]="STRING",e[e.BYTES=12]="BYTES",e[e.UINT32=13]="UINT32",e[e.SFIXED32=15]="SFIXED32",e[e.SFIXED64=16]="SFIXED64",e[e.SINT32=17]="SINT32",e[e.SINT64=18]="SINT64"})(g||(g={}));function Zc(){let e=0,t=0;for(let r=0;r<28;r+=7){let a=this.buf[this.pos++];if(e|=(a&127)<>4,(n&128)==0)return this.assertBounds(),[e,t];for(let r=3;r<=31;r+=7){let a=this.buf[this.pos++];if(t|=(a&127)<>>s,o=!(!(i>>>7)&&t==0),l=(o?i|128:i)&255;if(n.push(l),!o)return}const r=e>>>28&15|(t&7)<<4,a=t>>3!=0;if(n.push((a?r|128:r)&255),!!a){for(let s=3;s<31;s=s+7){const i=t>>>s,o=!!(i>>>7),l=(o?i|128:i)&255;if(n.push(l),!o)return}n.push(t>>>31&1)}}const Mn=4294967296;function cs(e){const t=e[0]==="-";t&&(e=e.slice(1));const n=1e6;let r=0,a=0;function s(i,o){const l=Number(e.slice(i,o));a*=n,r=r*n+l,r>=Mn&&(a=a+(r/Mn|0),r=r%Mn)}return s(-24,-18),s(-18,-12),s(-12,-6),s(-6),t?_o(r,a):Ea(r,a)}function Cc(e,t){let n=Ea(e,t);const r=n.hi&2147483648;r&&(n=_o(n.lo,n.hi));const a=yo(n.lo,n.hi);return r?"-"+a:a}function yo(e,t){if({lo:e,hi:t}=Mc(e,t),t<=2097151)return String(Mn*t+e);const n=e&16777215,r=(e>>>24|t<<8)&16777215,a=t>>16&65535;let s=n+r*6777216+a*6710656,i=r+a*8147497,o=a*2;const l=1e7;return s>=l&&(i+=Math.floor(s/l),s%=l),i>=l&&(o+=Math.floor(i/l),i%=l),o.toString()+fs(i)+fs(s)}function Mc(e,t){return{lo:e>>>0,hi:t>>>0}}function Ea(e,t){return{lo:e|0,hi:t|0}}function _o(e,t){return t=~t,e?e=~e+1:t+=1,Ea(e,t)}const fs=e=>{const t=String(e);return"0000000".slice(t.length)+t};function jr(e,t){if(e>=0){for(;e>127;)t.push(e&127|128),e=e>>>7;t.push(e)}else{for(let n=0;n<9;n++)t.push(e&127|128),e=e>>7;t.push(1)}}function Yc(){let e=this.buf[this.pos++],t=e&127;if((e&128)==0)return this.assertBounds(),t;if(e=this.buf[this.pos++],t|=(e&127)<<7,(e&128)==0)return this.assertBounds(),t;if(e=this.buf[this.pos++],t|=(e&127)<<14,(e&128)==0)return this.assertBounds(),t;if(e=this.buf[this.pos++],t|=(e&127)<<21,(e&128)==0)return this.assertBounds(),t;e=this.buf[this.pos++],t|=(e&15)<<28;for(let n=5;(e&128)!==0&&n<10;n++)e=this.buf[this.pos++];if((e&128)!=0)throw new Error("invalid varint");return this.assertBounds(),t>>>0}var ds={};const z=Bc();function Bc(){const e=new DataView(new ArrayBuffer(8));if(typeof BigInt=="function"&&typeof e.getBigInt64=="function"&&typeof e.getBigUint64=="function"&&typeof e.setBigInt64=="function"&&typeof e.setBigUint64=="function"&&(!!globalThis.Deno||typeof process!="object"||typeof ds!="object"||ds.BUF_BIGINT_DISABLE!=="1")){const n=BigInt("-9223372036854775808"),r=BigInt("9223372036854775807"),a=BigInt("0"),s=BigInt("18446744073709551615");return{zero:BigInt(0),supported:!0,parse(i){const o=typeof i=="bigint"?i:BigInt(i);if(o>r||os||or.localName===n)}function Xc(e,t){const n=t.localName;if(t.oneof)return e[t.oneof.localName].case===n;if(t.presence!=Eo)return e[n]!==void 0&&Object.prototype.hasOwnProperty.call(e,n);switch(t.fieldKind){case"list":return e[n].length>0;case"map":return Object.keys(e[n]).length>0;case"scalar":return!Pc(t.scalar,e[n]);case"enum":return e[n]!==t.enum.values[0].number}throw new Error("message field with implicit presence")}function un(e,t){return Object.prototype.hasOwnProperty.call(e,t)&&e[t]!==void 0}function wo(e,t){if(t.oneof){const n=e[t.oneof.localName];return n.case===t.localName?n.value:void 0}return e[t.localName]}function Io(e,t,n){t.oneof?e[t.oneof.localName]={case:t.localName,value:n}:e[t.localName]=n}function Jc(e,t){const n=t.localName;if(t.oneof){const r=t.oneof.localName;e[r].case===n&&(e[r]={case:void 0})}else if(t.presence!=Eo)delete e[n];else switch(t.fieldKind){case"map":e[n]={};break;case"list":e[n]=[];break;case"enum":e[n]=t.enum.values[0].number;break;case"scalar":e[n]=Wt(t.scalar,t.longAsString);break}}function ut(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Na(e,t){var n,r,a,s;if(ut(e)&&$e in e&&"add"in e&&"field"in e&&typeof e.field=="function"){if(t!==void 0){const i=t,o=e.field();return i.listKind==o.listKind&&i.scalar===o.scalar&&((n=i.message)===null||n===void 0?void 0:n.typeName)===((r=o.message)===null||r===void 0?void 0:r.typeName)&&((a=i.enum)===null||a===void 0?void 0:a.typeName)===((s=o.enum)===null||s===void 0?void 0:s.typeName)}return!0}return!1}function wa(e,t){var n,r,a,s;if(ut(e)&&$e in e&&"has"in e&&"field"in e&&typeof e.field=="function"){if(t!==void 0){const i=t,o=e.field();return i.mapKey===o.mapKey&&i.mapKind==o.mapKind&&i.scalar===o.scalar&&((n=i.message)===null||n===void 0?void 0:n.typeName)===((r=o.message)===null||r===void 0?void 0:r.typeName)&&((a=i.enum)===null||a===void 0?void 0:a.typeName)===((s=o.enum)===null||s===void 0?void 0:s.typeName)}return!0}return!1}function mr(e,t){return ut(e)&&$e in e&&"desc"in e&&ut(e.desc)&&e.desc.kind==="message"&&(t===void 0||e.desc.typeName==t.typeName)}function Kc(e){return xo(e.$typeName)}function xn(e){const t=e.fields[0];return xo(e.typeName)&&t!==void 0&&t.fieldKind=="scalar"&&t.name=="value"&&t.number==1}function xo(e){return e.startsWith("google.protobuf.")&&["DoubleValue","FloatValue","Int64Value","UInt64Value","Int32Value","UInt32Value","BoolValue","StringValue","BytesValue"].includes(e.substring(16))}const jc=999,zc=998,Yn=2;function Se(e,t){if(_a(t,e))return t;const n=ef(e);return t!==void 0&&Hc(e,n,t),n}function Hc(e,t,n){for(const r of e.members){let a=n[r.localName];if(a==null)continue;let s;if(r.kind=="oneof"){const i=No(n,r);if(!i)continue;s=i,a=wo(n,i)}else s=r;switch(s.fieldKind){case"message":a=Ia(s,a);break;case"scalar":a=So(s,a);break;case"list":a=Qc(s,a);break;case"map":a=$c(s,a);break}Io(t,s,a)}return t}function So(e,t){return e.scalar==g.BYTES?xa(t):t}function $c(e,t){if(ut(t)){if(e.scalar==g.BYTES)return bs(t,xa);if(e.mapKind=="message")return bs(t,n=>Ia(e,n))}return t}function Qc(e,t){if(Array.isArray(t)){if(e.scalar==g.BYTES)return t.map(xa);if(e.listKind=="message")return t.map(n=>Ia(e,n))}return t}function Ia(e,t){if(e.fieldKind=="message"&&!e.oneof&&xn(e.message))return So(e.message.fields[0],t);if(ut(t)){if(e.message.typeName=="google.protobuf.Struct"&&e.parent.typeName!=="google.protobuf.Value")return t;if(!_a(t,e.message))return Se(e.message,t)}return t}function xa(e){return Array.isArray(e)?new Uint8Array(e):e}function bs(e,t){const n={};for(const r of Object.entries(e))n[r[0]]=t(r[1]);return n}const qc=Symbol(),vs=new WeakMap;function ef(e){let t;if(tf(e)){const n=vs.get(e);let r,a;if(n)({prototype:r,members:a}=n);else{r={},a=new Set;for(const s of e.members)s.kind!="oneof"&&(s.fieldKind!="scalar"&&s.fieldKind!="enum"||s.presence!=Yn&&(a.add(s),r[s.localName]=kr(s)));vs.set(e,{prototype:r,members:a})}t=Object.create(r),t.$typeName=e.typeName;for(const s of e.members)a.has(s)||s.kind=="field"&&(s.fieldKind=="message"||(s.fieldKind=="scalar"||s.fieldKind=="enum")&&s.presence!=Yn)||(t[s.localName]=kr(s))}else{t={$typeName:e.typeName};for(const n of e.members)(n.kind=="oneof"||n.presence==Yn)&&(t[n.localName]=kr(n))}return t}function tf(e){switch(e.file.edition){case jc:return!1;case zc:return!0;default:return e.fields.some(t=>t.presence!=Yn&&t.fieldKind!="message"&&!t.oneof)}}function kr(e){if(e.kind=="oneof")return{case:void 0};if(e.fieldKind=="list")return[];if(e.fieldKind=="map")return{};if(e.fieldKind=="message")return qc;const t=e.getDefaultValue();return t!==void 0?e.fieldKind=="scalar"&&e.longAsString?t.toString():t:e.fieldKind=="scalar"?Wt(e.scalar,e.longAsString):e.enum.values[0].number}const nf=["FieldValueInvalidError","FieldListRangeError","ForeignFieldError"];class xe extends Error{constructor(t,n,r="FieldValueInvalidError"){super(n),this.name=r,this.field=()=>t}}function rf(e){return e instanceof Error&&nf.includes(e.name)&&"field"in e&&typeof e.field=="function"}const Rr=Symbol.for("@bufbuild/protobuf/text-encoding");function Sa(){if(globalThis[Rr]==null){const e=new globalThis.TextEncoder,t=new globalThis.TextDecoder;globalThis[Rr]={encodeUtf8(n){return e.encode(n)},decodeUtf8(n){return t.decode(n)},checkUtf8(n){try{return encodeURIComponent(n),!0}catch{return!1}}}}return globalThis[Rr]}var ee;(function(e){e[e.Varint=0]="Varint",e[e.Bit64=1]="Bit64",e[e.LengthDelimited=2]="LengthDelimited",e[e.StartGroup=3]="StartGroup",e[e.EndGroup=4]="EndGroup",e[e.Bit32=5]="Bit32"})(ee||(ee={}));const To=34028234663852886e22,Ao=-34028234663852886e22,ko=4294967295,Ro=2147483647,Oo=-2147483648;class Vo{constructor(t=Sa().encodeUtf8){this.encodeUtf8=t,this.stack=[],this.chunks=[],this.buf=[]}finish(){this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]);let t=0;for(let a=0;a>>0)}raw(t){return this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]),this.chunks.push(t),this}uint32(t){for(gs(t);t>127;)this.buf.push(t&127|128),t=t>>>7;return this.buf.push(t),this}int32(t){return Or(t),jr(t,this.buf),this}bool(t){return this.buf.push(t?1:0),this}bytes(t){return this.uint32(t.byteLength),this.raw(t)}string(t){let n=this.encodeUtf8(t);return this.uint32(n.byteLength),this.raw(n)}float(t){af(t);let n=new Uint8Array(4);return new DataView(n.buffer).setFloat32(0,t,!0),this.raw(n)}double(t){let n=new Uint8Array(8);return new DataView(n.buffer).setFloat64(0,t,!0),this.raw(n)}fixed32(t){gs(t);let n=new Uint8Array(4);return new DataView(n.buffer).setUint32(0,t,!0),this.raw(n)}sfixed32(t){Or(t);let n=new Uint8Array(4);return new DataView(n.buffer).setInt32(0,t,!0),this.raw(n)}sint32(t){return Or(t),t=(t<<1^t>>31)>>>0,jr(t,this.buf),this}sfixed64(t){let n=new Uint8Array(8),r=new DataView(n.buffer),a=z.enc(t);return r.setInt32(0,a.lo,!0),r.setInt32(4,a.hi,!0),this.raw(n)}fixed64(t){let n=new Uint8Array(8),r=new DataView(n.buffer),a=z.uEnc(t);return r.setInt32(0,a.lo,!0),r.setInt32(4,a.hi,!0),this.raw(n)}int64(t){let n=z.enc(t);return Tr(n.lo,n.hi,this.buf),this}sint64(t){const n=z.enc(t),r=n.hi>>31,a=n.lo<<1^r,s=(n.hi<<1|n.lo>>>31)^r;return Tr(a,s,this.buf),this}uint64(t){const n=z.uEnc(t);return Tr(n.lo,n.hi,this.buf),this}}class Ta{constructor(t,n=Sa().decodeUtf8){this.decodeUtf8=n,this.varint64=Zc,this.uint32=Yc,this.buf=t,this.len=t.length,this.pos=0,this.view=new DataView(t.buffer,t.byteOffset,t.byteLength)}tag(){let t=this.uint32(),n=t>>>3,r=t&7;if(n<=0||r<0||r>5)throw new Error("illegal tag: field no "+n+" wire type "+r);return[n,r]}skip(t,n){let r=this.pos;switch(t){case ee.Varint:for(;this.buf[this.pos++]&128;);break;case ee.Bit64:this.pos+=4;case ee.Bit32:this.pos+=4;break;case ee.LengthDelimited:let a=this.uint32();this.pos+=a;break;case ee.StartGroup:for(;;){const[s,i]=this.tag();if(i===ee.EndGroup){if(n!==void 0&&s!==n)throw new Error("invalid end group tag");break}this.skip(i,s)}break;default:throw new Error("cant skip wire type "+t)}return this.assertBounds(),this.buf.subarray(r,this.pos)}assertBounds(){if(this.pos>this.len)throw new RangeError("premature EOF")}int32(){return this.uint32()|0}sint32(){let t=this.uint32();return t>>>1^-(t&1)}int64(){return z.dec(...this.varint64())}uint64(){return z.uDec(...this.varint64())}sint64(){let[t,n]=this.varint64(),r=-(t&1);return t=(t>>>1|(n&1)<<31)^r,n=n>>>1^r,z.dec(t,n)}bool(){let[t,n]=this.varint64();return t!==0||n!==0}fixed32(){return this.view.getUint32((this.pos+=4)-4,!0)}sfixed32(){return this.view.getInt32((this.pos+=4)-4,!0)}fixed64(){return z.uDec(this.sfixed32(),this.sfixed32())}sfixed64(){return z.dec(this.sfixed32(),this.sfixed32())}float(){return this.view.getFloat32((this.pos+=4)-4,!0)}double(){return this.view.getFloat64((this.pos+=8)-8,!0)}bytes(){let t=this.uint32(),n=this.pos;return this.pos+=t,this.assertBounds(),this.buf.subarray(n,n+t)}string(){return this.decodeUtf8(this.bytes())}}function Or(e){if(typeof e=="string")e=Number(e);else if(typeof e!="number")throw new Error("invalid int32: "+typeof e);if(!Number.isInteger(e)||e>Ro||eko||e<0)throw new Error("invalid uint32: "+e)}function af(e){if(typeof e=="string"){const t=e;if(e=Number(e),Number.isNaN(e)&&t!=="NaN")throw new Error("invalid float32: "+t)}else if(typeof e!="number")throw new Error("invalid float32: "+typeof e);if(Number.isFinite(e)&&(e>To||en.number===t):mr(t,e.message)}function Go(e,t){switch(t){case g.DOUBLE:return typeof e=="number";case g.FLOAT:return typeof e!="number"?!1:Number.isNaN(e)||!Number.isFinite(e)?!0:e>To||eRo||eko||e<0?`${e.toFixed()} out of range`:!0;case g.BOOL:return typeof e=="boolean";case g.STRING:return typeof e!="string"?!1:Sa().checkUtf8(e)||"invalid UTF8";case g.BYTES:return e instanceof Uint8Array;case g.INT64:case g.SFIXED64:case g.SINT64:if(typeof e=="bigint"||typeof e=="number"||typeof e=="string"&&e.length>0)try{return z.parse(e),!0}catch{return`${e} out of range`}return!1;case g.FIXED64:case g.UINT64:if(typeof e=="bigint"||typeof e=="number"||typeof e=="string"&&e.length>0)try{return z.uParse(e),!0}catch{return`${e} out of range`}return!1}}function jn(e,t,n){return n=typeof n=="string"?`: ${n}`:`, got ${ce(t)}`,e.scalar!==void 0?`expected ${of(e.scalar)}`+n:e.enum!==void 0?`expected ${e.enum.toString()}`+n:`expected ${Lo(e.message)}`+n}function ce(e){switch(typeof e){case"object":return e===null?"null":e instanceof Uint8Array?`Uint8Array(${e.length})`:Array.isArray(e)?`Array(${e.length})`:Na(e)?Fo(e.field()):wa(e)?Uo(e.field()):mr(e)?Lo(e.desc):_a(e)?`message ${e.$typeName}`:"object";case"string":return e.length>30?"string":`"${e.split('"').join('\\"')}"`;case"boolean":return String(e);case"number":return String(e);case"bigint":return String(e)+"n";default:return typeof e}}function Lo(e){return`ReflectMessage (${e.typeName})`}function Fo(e){switch(e.listKind){case"message":return`ReflectList (${e.message.toString()})`;case"enum":return`ReflectList (${e.enum.toString()})`;case"scalar":return`ReflectList (${g[e.scalar]})`}}function Uo(e){switch(e.mapKind){case"message":return`ReflectMap (${g[e.mapKey]}, ${e.message.toString()})`;case"enum":return`ReflectMap (${g[e.mapKey]}, ${e.enum.toString()})`;case"scalar":return`ReflectMap (${g[e.mapKey]}, ${g[e.scalar]})`}}function of(e){switch(e){case g.STRING:return"string";case g.BOOL:return"boolean";case g.INT64:case g.SINT64:case g.SFIXED64:return"bigint (int64)";case g.UINT64:case g.FIXED64:return"bigint (uint64)";case g.BYTES:return"Uint8Array";case g.DOUBLE:return"number (float64)";case g.FLOAT:return"number (float32)";case g.FIXED32:case g.UINT32:return"number (uint32)";case g.INT32:case g.SFIXED32:case g.SINT32:return"number (int32)"}}function be(e,t,n=!0){return new Do(e,t,n)}const ys=new WeakMap;class Do{get sortedFields(){const t=ys.get(this.desc);if(t)return t;const n=this.desc.fields.concat().sort((r,a)=>r.number-a.number);return ys.set(this.desc,n),n}constructor(t,n,r=!0){this.lists=new Map,this.maps=new Map,this.check=r,this.desc=t,this.message=this[$e]=n??Se(t),this.fields=t.fields,this.oneofs=t.oneofs,this.members=t.members}findNumber(t){return this._fieldsByNumber||(this._fieldsByNumber=new Map(this.desc.fields.map(n=>[n.number,n]))),this._fieldsByNumber.get(t)}oneofCase(t){return $t(this.message,t),No(this.message,t)}isSet(t){return $t(this.message,t),Xc(this.message,t)}clear(t){$t(this.message,t),Jc(this.message,t)}get(t){$t(this.message,t);const n=wo(this.message,t);switch(t.fieldKind){case"list":let r=this.lists.get(t);return(!r||r[$e]!==n)&&this.lists.set(t,r=new lf(t,n,this.check)),r;case"map":let a=this.maps.get(t);return(!a||a[$e]!==n)&&this.maps.set(t,a=new uf(t,n,this.check)),a;case"message":return Ra(t,n,this.check);case"scalar":return n===void 0?Wt(t.scalar,!1):Oa(t,n);case"enum":return n??t.enum.values[0].number}}set(t,n){if($t(this.message,t),this.check){const a=bt(t,n);if(a)throw a}let r;t.fieldKind=="message"?r=ka(t,n):wa(n)||Na(n)?r=n[$e]:r=Va(t,n),Io(this.message,t,r)}getUnknown(){return this.message.$unknown}setUnknown(t){this.message.$unknown=t}}function $t(e,t){if(t.parent.typeName!==e.$typeName)throw new xe(t,`cannot use ${t.toString()} with message ${e.$typeName}`,"ForeignFieldError")}class lf{field(){return this._field}get size(){return this._arr.length}constructor(t,n,r){this._field=t,this._arr=this[$e]=n,this.check=r}get(t){const n=this._arr[t];return n===void 0?void 0:Vr(this._field,n,this.check)}set(t,n){if(t<0||t>=this._arr.length)throw new xe(this._field,`list item #${t+1}: out of range`);if(this.check){const r=hs(this._field,t,n);if(r)throw r}this._arr[t]=_s(this._field,n)}add(t){if(this.check){const n=hs(this._field,this._arr.length,t);if(n)throw n}this._arr.push(_s(this._field,t))}clear(){this._arr.splice(0,this._arr.length)}[Symbol.iterator](){return this.values()}keys(){return this._arr.keys()}*values(){for(const t of this._arr)yield Vr(this._field,t,this.check)}*entries(){for(let t=0;t0&&t.setUnknown([...n]),t}function Lr(e,t){return e.message!==void 0&&mr(t)?Bo(t):e.scalar==g.BYTES&&t instanceof Uint8Array?t.slice():t}function Ga(e){const t=ff();let n=e.length*3/4;e[e.length-2]=="="?n-=2:e[e.length-1]=="="&&(n-=1);let r=new Uint8Array(n),a=0,s=0,i,o=0;for(let l=0;l>4,o=i,s=2;break;case 2:r[a++]=(o&15)<<4|(i&60)>>2,o=i,s=3;break;case 3:r[a++]=(o&3)<<6|i,s=0;break}}if(s==1)throw Error("invalid base64 string");return r.subarray(0,a)}function Po(e,t="std"){const n=Xo(t),r=t=="std";let a="",s=0,i,o=0;for(let l=0;l>2],o=(i&3)<<4,s=1;break;case 1:a+=n[o|i>>4],o=(i&15)<<2,s=2;break;case 2:a+=n[o|i>>6],a+=n[i&63],s=0;break}return s&&(a+=n[o],r&&(a+="=",s==1&&(a+="="))),a}let On,Ns,Vt;function Xo(e){return On||(On="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),Ns=On.slice(0,-2).concat("-","_")),e=="url"?Ns:On}function ff(){if(!Vt){Vt=[];const e=Xo("std");for(let t=0;t"_"+t.toLowerCase())}const df=new Set(["constructor","toString","toJSON","valueOf"]);function cn(e){return df.has(e)?e+"$":e}function La(e){for(const t of e.field)un(t,"jsonName")||(t.jsonName=Zt(t.name));e.nestedType.forEach(La)}function mf(e,t){const n=e.values.find(r=>r.name===t);if(!n)throw new Error(`cannot parse ${e} default value: ${t}`);return n.number}function pf(e,t){switch(e){case g.STRING:return t;case g.BYTES:{const n=bf(t);if(n===!1)throw new Error(`cannot parse ${g[e]} default value: ${t}`);return n}case g.INT64:case g.SFIXED64:case g.SINT64:return z.parse(t);case g.UINT64:case g.FIXED64:return z.uParse(t);case g.DOUBLE:case g.FLOAT:switch(t){case"inf":return Number.POSITIVE_INFINITY;case"-inf":return Number.NEGATIVE_INFINITY;case"nan":return Number.NaN;default:return parseFloat(t)}case g.BOOL:return t==="true";case g.INT32:case g.UINT32:case g.SINT32:case g.FIXED32:case g.SFIXED32:return parseInt(t,10)}}function bf(e){const t=[],n={tail:e,c:"",next(){return this.tail.length==0?!1:(this.c=this.tail[0],this.tail=this.tail.substring(1),!0)},take(r){if(this.tail.length>=r){const a=this.tail.substring(0,r);return this.tail=this.tail.substring(r),a}return!1}};for(;n.next();)switch(n.c){case"\\":if(n.next())switch(n.c){case"\\":t.push(n.c.charCodeAt(0));break;case"b":t.push(8);break;case"f":t.push(12);break;case"n":t.push(10);break;case"r":t.push(13);break;case"t":t.push(9);break;case"v":t.push(11);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":{const r=n.c,a=n.take(2);if(a===!1)return!1;const s=parseInt(r+a,8);if(Number.isNaN(s))return!1;t.push(s);break}case"x":{const r=n.c,a=n.take(2);if(a===!1)return!1;const s=parseInt(r+a,16);if(Number.isNaN(s))return!1;t.push(s);break}case"u":{const r=n.c,a=n.take(4);if(a===!1)return!1;const s=parseInt(r+a,16);if(Number.isNaN(s))return!1;const i=new Uint8Array(4);new DataView(i.buffer).setInt32(0,s,!0),t.push(i[0],i[1],i[2],i[3]);break}case"U":{const r=n.c,a=n.take(8);if(a===!1)return!1;const s=z.uEnc(r+a),i=new Uint8Array(8),o=new DataView(i.buffer);o.setInt32(0,s.lo,!0),o.setInt32(4,s.hi,!0),t.push(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7]);break}}break;default:t.push(n.c.charCodeAt(0))}return new Uint8Array(t)}function*zr(e){switch(e.kind){case"file":for(const t of e.messages)yield t,yield*zr(t);yield*e.enums,yield*e.services,yield*e.extensions;break;case"message":for(const t of e.nestedMessages)yield t,yield*zr(t);yield*e.nestedEnums,yield*e.nestedExtensions;break}}function Ko(...e){const t=vf();if(!e.length)return t;if("$typeName"in e[0]&&e[0].$typeName=="google.protobuf.FileDescriptorSet"){for(const r of e[0].file)Ss(r,t);return t}if("$typeName"in e[0]){let i=function(o){const l=[];for(const u of o.dependency){if(t.getFile(u)!=null||s.has(u))continue;const c=a(u);if(!c)throw new Error(`Unable to resolve ${u}, imported by ${o.name}`);"kind"in c?t.addFile(c,!1,!0):(s.add(c.name),l.push(c))}return l.concat(...l.map(i))};var n=i;const r=e[0],a=e[1],s=new Set;for(const o of[r,...i(r)].reverse())Ss(o,t)}else for(const r of e)for(const a of r.files)t.addFile(a);return t}function vf(){const e=new Map,t=new Map,n=new Map;return{kind:"registry",types:e,extendees:t,[Symbol.iterator](){return e.values()},get files(){return n.values()},addFile(r,a,s){if(n.set(r.proto.name,r),!a)for(const i of zr(r))this.add(i);if(s)for(const i of r.dependencies)this.addFile(i,a,s)},add(r){if(r.kind=="extension"){let a=t.get(r.extendee.typeName);a||t.set(r.extendee.typeName,a=new Map),a.set(r.number,r)}e.set(r.typeName,r)},get(r){return e.get(r)},getFile(r){return n.get(r)},getMessage(r){const a=e.get(r);return a?.kind=="message"?a:void 0},getEnum(r){const a=e.get(r);return a?.kind=="enum"?a:void 0},getExtension(r){const a=e.get(r);return a?.kind=="extension"?a:void 0},getExtensionFor(r,a){var s;return(s=t.get(r.typeName))===null||s===void 0?void 0:s.get(a)},getService(r){const a=e.get(r);return a?.kind=="service"?a:void 0}}}const gf=998,hf=999,yf=9,fn=10,sn=11,_f=12,ws=14,Fa=3,Ef=2,Is=1,Nf=0,Fr=1,xs=2,wf=3,If=1,xf=2,Sf=1,jo={998:{fieldPresence:1,enumType:2,repeatedFieldEncoding:2,utf8Validation:3,messageEncoding:1,jsonFormat:2,enforceNamingStyle:2,defaultSymbolVisibility:1},999:{fieldPresence:2,enumType:1,repeatedFieldEncoding:1,utf8Validation:2,messageEncoding:1,jsonFormat:1,enforceNamingStyle:2,defaultSymbolVisibility:1},1e3:{fieldPresence:1,enumType:1,repeatedFieldEncoding:1,utf8Validation:2,messageEncoding:1,jsonFormat:1,enforceNamingStyle:2,defaultSymbolVisibility:1},1001:{fieldPresence:1,enumType:1,repeatedFieldEncoding:1,utf8Validation:2,messageEncoding:1,jsonFormat:1,enforceNamingStyle:1,defaultSymbolVisibility:2}};function Ss(e,t){var n,r;const a={kind:"file",proto:e,deprecated:(r=(n=e.options)===null||n===void 0?void 0:n.deprecated)!==null&&r!==void 0?r:!1,edition:Rf(e),name:e.name.replace(/\.proto$/,""),dependencies:Of(e,t),enums:[],messages:[],extensions:[],services:[],toString(){return`file ${e.name}`}},s=new Map,i={get(o){return s.get(o)},add(o){var l;Ue(((l=o.proto.options)===null||l===void 0?void 0:l.mapEntry)===!0),s.set(o.typeName,o)}};for(const o of e.enumType)zo(o,a,void 0,t);for(const o of e.messageType)Ho(o,a,void 0,t,i);for(const o of e.service)Tf(o,a,t);Hr(a,t);for(const o of s.values())$r(o,t,i);for(const o of a.messages)$r(o,t,i),Hr(o,t);t.addFile(a,!0)}function Hr(e,t){switch(e.kind){case"file":for(const n of e.proto.extension){const r=Qr(n,e,t);e.extensions.push(r),t.add(r)}break;case"message":for(const n of e.proto.extension){const r=Qr(n,e,t);e.nestedExtensions.push(r),t.add(r)}for(const n of e.nestedMessages)Hr(n,t);break}}function $r(e,t,n){const r=e.proto.oneofDecl.map(s=>kf(s,e)),a=new Set;for(const s of e.proto.field){const i=Lf(s,r),o=Qr(s,e,t,i,n);e.fields.push(o),e.field[o.localName]=o,i===void 0?e.members.push(o):(i.fields.push(o),a.has(i)||(a.add(i),e.members.push(i)))}for(const s of r.filter(i=>a.has(i)))e.oneofs.push(s);for(const s of e.nestedMessages)$r(s,t,n)}function zo(e,t,n,r){var a,s,i,o,l;const u=Vf(e.name,e.value),c={kind:"enum",proto:e,deprecated:(s=(a=e.options)===null||a===void 0?void 0:a.deprecated)!==null&&s!==void 0?s:!1,file:t,parent:n,open:!0,name:e.name,typeName:pr(e,n,t),value:{},values:[],sharedPrefix:u,toString(){return`enum ${this.typeName}`}};c.open=Wf(c),r.add(c);for(const m of e.value){const p=m.name;c.values.push(c.value[m.number]={kind:"enum_value",proto:m,deprecated:(o=(i=m.options)===null||i===void 0?void 0:i.deprecated)!==null&&o!==void 0?o:!1,parent:c,name:p,localName:cn(u==null?p:p.substring(u.length)),number:m.number,toString(){return`enum value ${c.typeName}.${p}`}})}((l=n?.nestedEnums)!==null&&l!==void 0?l:t.enums).push(c)}function Ho(e,t,n,r,a){var s,i,o,l;const u={kind:"message",proto:e,deprecated:(i=(s=e.options)===null||s===void 0?void 0:s.deprecated)!==null&&i!==void 0?i:!1,file:t,parent:n,name:e.name,typeName:pr(e,n,t),fields:[],field:{},oneofs:[],members:[],nestedEnums:[],nestedMessages:[],nestedExtensions:[],toString(){return`message ${this.typeName}`}};((o=e.options)===null||o===void 0?void 0:o.mapEntry)===!0?a.add(u):(((l=n?.nestedMessages)!==null&&l!==void 0?l:t.messages).push(u),r.add(u));for(const c of e.enumType)zo(c,t,u,r);for(const c of e.nestedType)Ho(c,t,u,r,a)}function Tf(e,t,n){var r,a;const s={kind:"service",proto:e,deprecated:(a=(r=e.options)===null||r===void 0?void 0:r.deprecated)!==null&&a!==void 0?a:!1,file:t,name:e.name,typeName:pr(e,void 0,t),methods:[],method:{},toString(){return`service ${this.typeName}`}};t.services.push(s),n.add(s);for(const i of e.method){const o=Af(i,s,n);s.methods.push(o),s.method[o.localName]=o}}function Af(e,t,n){var r,a,s,i;let o;e.clientStreaming&&e.serverStreaming?o="bidi_streaming":e.clientStreaming?o="client_streaming":e.serverStreaming?o="server_streaming":o="unary";const l=n.getMessage(ze(e.inputType)),u=n.getMessage(ze(e.outputType));Ue(l,`invalid MethodDescriptorProto: input_type ${e.inputType} not found`),Ue(u,`invalid MethodDescriptorProto: output_type ${e.inputType} not found`);const c=e.name;return{kind:"rpc",proto:e,deprecated:(a=(r=e.options)===null||r===void 0?void 0:r.deprecated)!==null&&a!==void 0?a:!1,parent:t,name:c,localName:cn(c.length?cn(c[0].toLowerCase()+c.substring(1)):c),methodKind:o,input:l,output:u,idempotency:(i=(s=e.options)===null||s===void 0?void 0:s.idempotencyLevel)!==null&&i!==void 0?i:Nf,toString(){return`rpc ${t.typeName}.${c}`}}}function kf(e,t){return{kind:"oneof",proto:e,deprecated:!1,parent:t,fields:[],name:e.name,localName:cn(Zt(e.name)),toString(){return`oneof ${t.typeName}.${this.name}`}}}function Qr(e,t,n,r,a){var s,i,o;const l=a===void 0,u={kind:"field",proto:e,deprecated:(i=(s=e.options)===null||s===void 0?void 0:s.deprecated)!==null&&i!==void 0?i:!1,name:e.name,number:e.number,scalar:void 0,message:void 0,enum:void 0,presence:Ff(e,r,l,t),listKind:void 0,mapKind:void 0,mapKey:void 0,delimitedEncoding:void 0,packed:void 0,longAsString:!1,getDefaultValue:void 0};if(l){const f=t.kind=="file"?t:t.file,b=t.kind=="file"?void 0:t,h=pr(e,b,f);u.kind="extension",u.file=f,u.parent=b,u.oneof=void 0,u.typeName=h,u.jsonName=`[${h}]`,u.toString=()=>`extension ${h}`;const v=n.getMessage(ze(e.extendee));Ue(v,`invalid FieldDescriptorProto: extendee ${e.extendee} not found`),u.extendee=v}else{const f=t;Ue(f.kind=="message"),u.parent=f,u.oneof=r,u.localName=r?Zt(e.name):cn(Zt(e.name)),u.jsonName=e.jsonName,u.toString=()=>`field ${f.typeName}.${e.name}`}const c=e.label,m=e.type,p=(o=e.options)===null||o===void 0?void 0:o.jstype;if(c===Fa){const f=m==sn?a?.get(ze(e.typeName)):void 0;if(f){u.fieldKind="map";const{key:b,value:h}=Df(f);return u.mapKey=b.scalar,u.mapKind=h.fieldKind,u.message=h.message,u.delimitedEncoding=!1,u.enum=h.enum,u.scalar=h.scalar,u}switch(u.fieldKind="list",m){case sn:case fn:u.listKind="message",u.message=n.getMessage(ze(e.typeName)),Ue(u.message),u.delimitedEncoding=Ts(e,t);break;case ws:u.listKind="enum",u.enum=n.getEnum(ze(e.typeName)),Ue(u.enum);break;default:u.listKind="scalar",u.scalar=m,u.longAsString=p==Is;break}return u.packed=Uf(e,t),u}switch(m){case sn:case fn:u.fieldKind="message",u.message=n.getMessage(ze(e.typeName)),Ue(u.message,`invalid FieldDescriptorProto: type_name ${e.typeName} not found`),u.delimitedEncoding=Ts(e,t),u.getDefaultValue=()=>{};break;case ws:{const f=n.getEnum(ze(e.typeName));Ue(f!==void 0,`invalid FieldDescriptorProto: type_name ${e.typeName} not found`),u.fieldKind="enum",u.enum=n.getEnum(ze(e.typeName)),u.getDefaultValue=()=>un(e,"defaultValue")?mf(f,e.defaultValue):void 0;break}default:{u.fieldKind="scalar",u.scalar=m,u.longAsString=p==Is,u.getDefaultValue=()=>un(e,"defaultValue")?pf(m,e.defaultValue):void 0;break}}return u}function Rf(e){switch(e.syntax){case"":case"proto2":return gf;case"proto3":return hf;case"editions":if(e.edition in jo)return e.edition;throw new Error(`${e.name}: unsupported edition`);default:throw new Error(`${e.name}: unsupported syntax "${e.syntax}"`)}}function Of(e,t){return e.dependency.map(n=>{const r=t.getFile(n);if(!r)throw new Error(`Cannot find ${n}, imported by ${e.name}`);return r})}function Vf(e,t){const n=Gf(e)+"_";for(const r of t){if(!r.name.toLowerCase().startsWith(n))return;const a=r.name.substring(n.length);if(a.length==0||/^\d/.test(a))return}return n}function Gf(e){return(e.substring(0,1)+e.substring(1).replace(/[A-Z]/g,t=>"_"+t)).toLowerCase()}function pr(e,t,n){let r;return t?r=`${t.typeName}.${e.name}`:n.proto.package.length>0?r=`${n.proto.package}.${e.name}`:r=`${e.name}`,r}function ze(e){return e.startsWith(".")?e.substring(1):e}function Lf(e,t){if(!un(e,"oneofIndex")||e.proto3Optional)return;const n=t[e.oneofIndex];return Ue(n,`invalid FieldDescriptorProto: oneof #${e.oneofIndex} for field #${e.number} not found`),n}function Ff(e,t,n,r){if(e.label==Ef)return wf;if(e.label==Fa)return xs;if(t||e.proto3Optional||n)return Fr;const a=Ct("fieldPresence",{proto:e,parent:r});return a==xs&&(e.type==sn||e.type==fn)?Fr:a}function Uf(e,t){if(e.label!=Fa)return!1;switch(e.type){case yf:case _f:case fn:case sn:return!1}const n=e.options;return n&&un(n,"packed")?n.packed:If==Ct("repeatedFieldEncoding",{proto:e,parent:t})}function Df(e){const t=e.fields.find(r=>r.number===1),n=e.fields.find(r=>r.number===2);return Ue(t&&t.fieldKind=="scalar"&&t.scalar!=g.BYTES&&t.scalar!=g.FLOAT&&t.scalar!=g.DOUBLE&&n&&n.fieldKind!="list"&&n.fieldKind!="map"),{key:t,value:n}}function Wf(e){var t;return Sf==Ct("enumType",{proto:e.proto,parent:(t=e.parent)!==null&&t!==void 0?t:e.file})}function Ts(e,t){return e.type==fn?!0:xf==Ct("messageEncoding",{proto:e,parent:t})}function Ct(e,t){var n,r;const a=(n=t.proto.options)===null||n===void 0?void 0:n.features;if(a){const s=a[e];if(s!=0)return s}if("kind"in t){if(t.kind=="message")return Ct(e,(r=t.parent)!==null&&r!==void 0?r:t.file);const s=jo[t.edition];if(!s)throw new Error(`feature default for edition ${t.edition} not found`);return s[e]}return Ct(e,t.parent)}function Ue(e,t){if(!e)throw new Error(t)}function Zf(e){const t=Cf(e);return t.messageType.forEach(La),Ko(t,()=>{}).getFile(t.name)}function Cf(e){return Object.assign(Object.create({syntax:"",edition:0}),Object.assign(Object.assign({$typeName:"google.protobuf.FileDescriptorProto",dependency:[],publicDependency:[],weakDependency:[],optionDependency:[],service:[],extension:[]},e),{messageType:e.messageType.map($o),enumType:e.enumType.map(Qo)}))}function $o(e){var t,n,r,a,s,i,o,l;return Object.assign(Object.create({visibility:0}),{$typeName:"google.protobuf.DescriptorProto",name:e.name,field:(n=(t=e.field)===null||t===void 0?void 0:t.map(Mf))!==null&&n!==void 0?n:[],extension:[],nestedType:(a=(r=e.nestedType)===null||r===void 0?void 0:r.map($o))!==null&&a!==void 0?a:[],enumType:(i=(s=e.enumType)===null||s===void 0?void 0:s.map(Qo))!==null&&i!==void 0?i:[],extensionRange:(l=(o=e.extensionRange)===null||o===void 0?void 0:o.map(c=>Object.assign({$typeName:"google.protobuf.DescriptorProto.ExtensionRange"},c)))!==null&&l!==void 0?l:[],oneofDecl:[],reservedRange:[],reservedName:[]})}function Mf(e){return Object.assign(Object.create({label:1,typeName:"",extendee:"",defaultValue:"",oneofIndex:0,jsonName:"",proto3Optional:!1}),Object.assign(Object.assign({$typeName:"google.protobuf.FieldDescriptorProto"},e),{options:e.options?Yf(e.options):void 0}))}function Yf(e){var t,n,r;return Object.assign(Object.create({ctype:0,packed:!1,jstype:0,lazy:!1,unverifiedLazy:!1,deprecated:!1,weak:!1,debugRedact:!1,retention:0}),Object.assign(Object.assign({$typeName:"google.protobuf.FieldOptions"},e),{targets:(t=e.targets)!==null&&t!==void 0?t:[],editionDefaults:(r=(n=e.editionDefaults)===null||n===void 0?void 0:n.map(s=>Object.assign({$typeName:"google.protobuf.FieldOptions.EditionDefault"},s)))!==null&&r!==void 0?r:[],uninterpretedOption:[]}))}function Qo(e){return Object.assign(Object.create({visibility:0}),{$typeName:"google.protobuf.EnumDescriptorProto",name:e.name,reservedName:[],reservedRange:[],value:e.value.map(n=>Object.assign({$typeName:"google.protobuf.EnumValueDescriptorProto"},n))})}function Le(e,t,...n){return n.reduce((r,a)=>r.nestedMessages[a],e.messages[t])}const Bf=Zf({name:"google/protobuf/descriptor.proto",package:"google.protobuf",messageType:[{name:"FileDescriptorSet",field:[{name:"file",number:1,type:11,label:3,typeName:".google.protobuf.FileDescriptorProto"}],extensionRange:[{start:536e6,end:536000001}]},{name:"FileDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"package",number:2,type:9,label:1},{name:"dependency",number:3,type:9,label:3},{name:"public_dependency",number:10,type:5,label:3},{name:"weak_dependency",number:11,type:5,label:3},{name:"option_dependency",number:15,type:9,label:3},{name:"message_type",number:4,type:11,label:3,typeName:".google.protobuf.DescriptorProto"},{name:"enum_type",number:5,type:11,label:3,typeName:".google.protobuf.EnumDescriptorProto"},{name:"service",number:6,type:11,label:3,typeName:".google.protobuf.ServiceDescriptorProto"},{name:"extension",number:7,type:11,label:3,typeName:".google.protobuf.FieldDescriptorProto"},{name:"options",number:8,type:11,label:1,typeName:".google.protobuf.FileOptions"},{name:"source_code_info",number:9,type:11,label:1,typeName:".google.protobuf.SourceCodeInfo"},{name:"syntax",number:12,type:9,label:1},{name:"edition",number:14,type:14,label:1,typeName:".google.protobuf.Edition"}]},{name:"DescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"field",number:2,type:11,label:3,typeName:".google.protobuf.FieldDescriptorProto"},{name:"extension",number:6,type:11,label:3,typeName:".google.protobuf.FieldDescriptorProto"},{name:"nested_type",number:3,type:11,label:3,typeName:".google.protobuf.DescriptorProto"},{name:"enum_type",number:4,type:11,label:3,typeName:".google.protobuf.EnumDescriptorProto"},{name:"extension_range",number:5,type:11,label:3,typeName:".google.protobuf.DescriptorProto.ExtensionRange"},{name:"oneof_decl",number:8,type:11,label:3,typeName:".google.protobuf.OneofDescriptorProto"},{name:"options",number:7,type:11,label:1,typeName:".google.protobuf.MessageOptions"},{name:"reserved_range",number:9,type:11,label:3,typeName:".google.protobuf.DescriptorProto.ReservedRange"},{name:"reserved_name",number:10,type:9,label:3},{name:"visibility",number:11,type:14,label:1,typeName:".google.protobuf.SymbolVisibility"}],nestedType:[{name:"ExtensionRange",field:[{name:"start",number:1,type:5,label:1},{name:"end",number:2,type:5,label:1},{name:"options",number:3,type:11,label:1,typeName:".google.protobuf.ExtensionRangeOptions"}]},{name:"ReservedRange",field:[{name:"start",number:1,type:5,label:1},{name:"end",number:2,type:5,label:1}]}]},{name:"ExtensionRangeOptions",field:[{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"},{name:"declaration",number:2,type:11,label:3,typeName:".google.protobuf.ExtensionRangeOptions.Declaration",options:{retention:2}},{name:"features",number:50,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"verification",number:3,type:14,label:1,typeName:".google.protobuf.ExtensionRangeOptions.VerificationState",defaultValue:"UNVERIFIED",options:{retention:2}}],nestedType:[{name:"Declaration",field:[{name:"number",number:1,type:5,label:1},{name:"full_name",number:2,type:9,label:1},{name:"type",number:3,type:9,label:1},{name:"reserved",number:5,type:8,label:1},{name:"repeated",number:6,type:8,label:1}]}],enumType:[{name:"VerificationState",value:[{name:"DECLARATION",number:0},{name:"UNVERIFIED",number:1}]}],extensionRange:[{start:1e3,end:536870912}]},{name:"FieldDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"number",number:3,type:5,label:1},{name:"label",number:4,type:14,label:1,typeName:".google.protobuf.FieldDescriptorProto.Label"},{name:"type",number:5,type:14,label:1,typeName:".google.protobuf.FieldDescriptorProto.Type"},{name:"type_name",number:6,type:9,label:1},{name:"extendee",number:2,type:9,label:1},{name:"default_value",number:7,type:9,label:1},{name:"oneof_index",number:9,type:5,label:1},{name:"json_name",number:10,type:9,label:1},{name:"options",number:8,type:11,label:1,typeName:".google.protobuf.FieldOptions"},{name:"proto3_optional",number:17,type:8,label:1}],enumType:[{name:"Type",value:[{name:"TYPE_DOUBLE",number:1},{name:"TYPE_FLOAT",number:2},{name:"TYPE_INT64",number:3},{name:"TYPE_UINT64",number:4},{name:"TYPE_INT32",number:5},{name:"TYPE_FIXED64",number:6},{name:"TYPE_FIXED32",number:7},{name:"TYPE_BOOL",number:8},{name:"TYPE_STRING",number:9},{name:"TYPE_GROUP",number:10},{name:"TYPE_MESSAGE",number:11},{name:"TYPE_BYTES",number:12},{name:"TYPE_UINT32",number:13},{name:"TYPE_ENUM",number:14},{name:"TYPE_SFIXED32",number:15},{name:"TYPE_SFIXED64",number:16},{name:"TYPE_SINT32",number:17},{name:"TYPE_SINT64",number:18}]},{name:"Label",value:[{name:"LABEL_OPTIONAL",number:1},{name:"LABEL_REPEATED",number:3},{name:"LABEL_REQUIRED",number:2}]}]},{name:"OneofDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"options",number:2,type:11,label:1,typeName:".google.protobuf.OneofOptions"}]},{name:"EnumDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"value",number:2,type:11,label:3,typeName:".google.protobuf.EnumValueDescriptorProto"},{name:"options",number:3,type:11,label:1,typeName:".google.protobuf.EnumOptions"},{name:"reserved_range",number:4,type:11,label:3,typeName:".google.protobuf.EnumDescriptorProto.EnumReservedRange"},{name:"reserved_name",number:5,type:9,label:3},{name:"visibility",number:6,type:14,label:1,typeName:".google.protobuf.SymbolVisibility"}],nestedType:[{name:"EnumReservedRange",field:[{name:"start",number:1,type:5,label:1},{name:"end",number:2,type:5,label:1}]}]},{name:"EnumValueDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"number",number:2,type:5,label:1},{name:"options",number:3,type:11,label:1,typeName:".google.protobuf.EnumValueOptions"}]},{name:"ServiceDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"method",number:2,type:11,label:3,typeName:".google.protobuf.MethodDescriptorProto"},{name:"options",number:3,type:11,label:1,typeName:".google.protobuf.ServiceOptions"}]},{name:"MethodDescriptorProto",field:[{name:"name",number:1,type:9,label:1},{name:"input_type",number:2,type:9,label:1},{name:"output_type",number:3,type:9,label:1},{name:"options",number:4,type:11,label:1,typeName:".google.protobuf.MethodOptions"},{name:"client_streaming",number:5,type:8,label:1,defaultValue:"false"},{name:"server_streaming",number:6,type:8,label:1,defaultValue:"false"}]},{name:"FileOptions",field:[{name:"java_package",number:1,type:9,label:1},{name:"java_outer_classname",number:8,type:9,label:1},{name:"java_multiple_files",number:10,type:8,label:1,defaultValue:"false"},{name:"java_generate_equals_and_hash",number:20,type:8,label:1,options:{deprecated:!0}},{name:"java_string_check_utf8",number:27,type:8,label:1,defaultValue:"false"},{name:"optimize_for",number:9,type:14,label:1,typeName:".google.protobuf.FileOptions.OptimizeMode",defaultValue:"SPEED"},{name:"go_package",number:11,type:9,label:1},{name:"cc_generic_services",number:16,type:8,label:1,defaultValue:"false"},{name:"java_generic_services",number:17,type:8,label:1,defaultValue:"false"},{name:"py_generic_services",number:18,type:8,label:1,defaultValue:"false"},{name:"deprecated",number:23,type:8,label:1,defaultValue:"false"},{name:"cc_enable_arenas",number:31,type:8,label:1,defaultValue:"true"},{name:"objc_class_prefix",number:36,type:9,label:1},{name:"csharp_namespace",number:37,type:9,label:1},{name:"swift_prefix",number:39,type:9,label:1},{name:"php_class_prefix",number:40,type:9,label:1},{name:"php_namespace",number:41,type:9,label:1},{name:"php_metadata_namespace",number:44,type:9,label:1},{name:"ruby_package",number:45,type:9,label:1},{name:"features",number:50,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],enumType:[{name:"OptimizeMode",value:[{name:"SPEED",number:1},{name:"CODE_SIZE",number:2},{name:"LITE_RUNTIME",number:3}]}],extensionRange:[{start:1e3,end:536870912}]},{name:"MessageOptions",field:[{name:"message_set_wire_format",number:1,type:8,label:1,defaultValue:"false"},{name:"no_standard_descriptor_accessor",number:2,type:8,label:1,defaultValue:"false"},{name:"deprecated",number:3,type:8,label:1,defaultValue:"false"},{name:"map_entry",number:7,type:8,label:1},{name:"deprecated_legacy_json_field_conflicts",number:11,type:8,label:1,options:{deprecated:!0}},{name:"features",number:12,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],extensionRange:[{start:1e3,end:536870912}]},{name:"FieldOptions",field:[{name:"ctype",number:1,type:14,label:1,typeName:".google.protobuf.FieldOptions.CType",defaultValue:"STRING"},{name:"packed",number:2,type:8,label:1},{name:"jstype",number:6,type:14,label:1,typeName:".google.protobuf.FieldOptions.JSType",defaultValue:"JS_NORMAL"},{name:"lazy",number:5,type:8,label:1,defaultValue:"false"},{name:"unverified_lazy",number:15,type:8,label:1,defaultValue:"false"},{name:"deprecated",number:3,type:8,label:1,defaultValue:"false"},{name:"weak",number:10,type:8,label:1,defaultValue:"false",options:{deprecated:!0}},{name:"debug_redact",number:16,type:8,label:1,defaultValue:"false"},{name:"retention",number:17,type:14,label:1,typeName:".google.protobuf.FieldOptions.OptionRetention"},{name:"targets",number:19,type:14,label:3,typeName:".google.protobuf.FieldOptions.OptionTargetType"},{name:"edition_defaults",number:20,type:11,label:3,typeName:".google.protobuf.FieldOptions.EditionDefault"},{name:"features",number:21,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"feature_support",number:22,type:11,label:1,typeName:".google.protobuf.FieldOptions.FeatureSupport"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],nestedType:[{name:"EditionDefault",field:[{name:"edition",number:3,type:14,label:1,typeName:".google.protobuf.Edition"},{name:"value",number:2,type:9,label:1}]},{name:"FeatureSupport",field:[{name:"edition_introduced",number:1,type:14,label:1,typeName:".google.protobuf.Edition"},{name:"edition_deprecated",number:2,type:14,label:1,typeName:".google.protobuf.Edition"},{name:"deprecation_warning",number:3,type:9,label:1},{name:"edition_removed",number:4,type:14,label:1,typeName:".google.protobuf.Edition"}]}],enumType:[{name:"CType",value:[{name:"STRING",number:0},{name:"CORD",number:1},{name:"STRING_PIECE",number:2}]},{name:"JSType",value:[{name:"JS_NORMAL",number:0},{name:"JS_STRING",number:1},{name:"JS_NUMBER",number:2}]},{name:"OptionRetention",value:[{name:"RETENTION_UNKNOWN",number:0},{name:"RETENTION_RUNTIME",number:1},{name:"RETENTION_SOURCE",number:2}]},{name:"OptionTargetType",value:[{name:"TARGET_TYPE_UNKNOWN",number:0},{name:"TARGET_TYPE_FILE",number:1},{name:"TARGET_TYPE_EXTENSION_RANGE",number:2},{name:"TARGET_TYPE_MESSAGE",number:3},{name:"TARGET_TYPE_FIELD",number:4},{name:"TARGET_TYPE_ONEOF",number:5},{name:"TARGET_TYPE_ENUM",number:6},{name:"TARGET_TYPE_ENUM_ENTRY",number:7},{name:"TARGET_TYPE_SERVICE",number:8},{name:"TARGET_TYPE_METHOD",number:9}]}],extensionRange:[{start:1e3,end:536870912}]},{name:"OneofOptions",field:[{name:"features",number:1,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],extensionRange:[{start:1e3,end:536870912}]},{name:"EnumOptions",field:[{name:"allow_alias",number:2,type:8,label:1},{name:"deprecated",number:3,type:8,label:1,defaultValue:"false"},{name:"deprecated_legacy_json_field_conflicts",number:6,type:8,label:1,options:{deprecated:!0}},{name:"features",number:7,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],extensionRange:[{start:1e3,end:536870912}]},{name:"EnumValueOptions",field:[{name:"deprecated",number:1,type:8,label:1,defaultValue:"false"},{name:"features",number:2,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"debug_redact",number:3,type:8,label:1,defaultValue:"false"},{name:"feature_support",number:4,type:11,label:1,typeName:".google.protobuf.FieldOptions.FeatureSupport"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],extensionRange:[{start:1e3,end:536870912}]},{name:"ServiceOptions",field:[{name:"features",number:34,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"deprecated",number:33,type:8,label:1,defaultValue:"false"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],extensionRange:[{start:1e3,end:536870912}]},{name:"MethodOptions",field:[{name:"deprecated",number:33,type:8,label:1,defaultValue:"false"},{name:"idempotency_level",number:34,type:14,label:1,typeName:".google.protobuf.MethodOptions.IdempotencyLevel",defaultValue:"IDEMPOTENCY_UNKNOWN"},{name:"features",number:35,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"uninterpreted_option",number:999,type:11,label:3,typeName:".google.protobuf.UninterpretedOption"}],enumType:[{name:"IdempotencyLevel",value:[{name:"IDEMPOTENCY_UNKNOWN",number:0},{name:"NO_SIDE_EFFECTS",number:1},{name:"IDEMPOTENT",number:2}]}],extensionRange:[{start:1e3,end:536870912}]},{name:"UninterpretedOption",field:[{name:"name",number:2,type:11,label:3,typeName:".google.protobuf.UninterpretedOption.NamePart"},{name:"identifier_value",number:3,type:9,label:1},{name:"positive_int_value",number:4,type:4,label:1},{name:"negative_int_value",number:5,type:3,label:1},{name:"double_value",number:6,type:1,label:1},{name:"string_value",number:7,type:12,label:1},{name:"aggregate_value",number:8,type:9,label:1}],nestedType:[{name:"NamePart",field:[{name:"name_part",number:1,type:9,label:2},{name:"is_extension",number:2,type:8,label:2}]}]},{name:"FeatureSet",field:[{name:"field_presence",number:1,type:14,label:1,typeName:".google.protobuf.FeatureSet.FieldPresence",options:{retention:1,targets:[4,1],editionDefaults:[{value:"EXPLICIT",edition:900},{value:"IMPLICIT",edition:999},{value:"EXPLICIT",edition:1e3}]}},{name:"enum_type",number:2,type:14,label:1,typeName:".google.protobuf.FeatureSet.EnumType",options:{retention:1,targets:[6,1],editionDefaults:[{value:"CLOSED",edition:900},{value:"OPEN",edition:999}]}},{name:"repeated_field_encoding",number:3,type:14,label:1,typeName:".google.protobuf.FeatureSet.RepeatedFieldEncoding",options:{retention:1,targets:[4,1],editionDefaults:[{value:"EXPANDED",edition:900},{value:"PACKED",edition:999}]}},{name:"utf8_validation",number:4,type:14,label:1,typeName:".google.protobuf.FeatureSet.Utf8Validation",options:{retention:1,targets:[4,1],editionDefaults:[{value:"NONE",edition:900},{value:"VERIFY",edition:999}]}},{name:"message_encoding",number:5,type:14,label:1,typeName:".google.protobuf.FeatureSet.MessageEncoding",options:{retention:1,targets:[4,1],editionDefaults:[{value:"LENGTH_PREFIXED",edition:900}]}},{name:"json_format",number:6,type:14,label:1,typeName:".google.protobuf.FeatureSet.JsonFormat",options:{retention:1,targets:[3,6,1],editionDefaults:[{value:"LEGACY_BEST_EFFORT",edition:900},{value:"ALLOW",edition:999}]}},{name:"enforce_naming_style",number:7,type:14,label:1,typeName:".google.protobuf.FeatureSet.EnforceNamingStyle",options:{retention:2,targets:[1,2,3,4,5,6,7,8,9],editionDefaults:[{value:"STYLE_LEGACY",edition:900},{value:"STYLE2024",edition:1001}]}},{name:"default_symbol_visibility",number:8,type:14,label:1,typeName:".google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility",options:{retention:2,targets:[1],editionDefaults:[{value:"EXPORT_ALL",edition:900},{value:"EXPORT_TOP_LEVEL",edition:1001}]}}],nestedType:[{name:"VisibilityFeature",enumType:[{name:"DefaultSymbolVisibility",value:[{name:"DEFAULT_SYMBOL_VISIBILITY_UNKNOWN",number:0},{name:"EXPORT_ALL",number:1},{name:"EXPORT_TOP_LEVEL",number:2},{name:"LOCAL_ALL",number:3},{name:"STRICT",number:4}]}]}],enumType:[{name:"FieldPresence",value:[{name:"FIELD_PRESENCE_UNKNOWN",number:0},{name:"EXPLICIT",number:1},{name:"IMPLICIT",number:2},{name:"LEGACY_REQUIRED",number:3}]},{name:"EnumType",value:[{name:"ENUM_TYPE_UNKNOWN",number:0},{name:"OPEN",number:1},{name:"CLOSED",number:2}]},{name:"RepeatedFieldEncoding",value:[{name:"REPEATED_FIELD_ENCODING_UNKNOWN",number:0},{name:"PACKED",number:1},{name:"EXPANDED",number:2}]},{name:"Utf8Validation",value:[{name:"UTF8_VALIDATION_UNKNOWN",number:0},{name:"VERIFY",number:2},{name:"NONE",number:3}]},{name:"MessageEncoding",value:[{name:"MESSAGE_ENCODING_UNKNOWN",number:0},{name:"LENGTH_PREFIXED",number:1},{name:"DELIMITED",number:2}]},{name:"JsonFormat",value:[{name:"JSON_FORMAT_UNKNOWN",number:0},{name:"ALLOW",number:1},{name:"LEGACY_BEST_EFFORT",number:2}]},{name:"EnforceNamingStyle",value:[{name:"ENFORCE_NAMING_STYLE_UNKNOWN",number:0},{name:"STYLE2024",number:1},{name:"STYLE_LEGACY",number:2}]}],extensionRange:[{start:1e3,end:9995},{start:9995,end:1e4},{start:1e4,end:10001}]},{name:"FeatureSetDefaults",field:[{name:"defaults",number:1,type:11,label:3,typeName:".google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault"},{name:"minimum_edition",number:4,type:14,label:1,typeName:".google.protobuf.Edition"},{name:"maximum_edition",number:5,type:14,label:1,typeName:".google.protobuf.Edition"}],nestedType:[{name:"FeatureSetEditionDefault",field:[{name:"edition",number:3,type:14,label:1,typeName:".google.protobuf.Edition"},{name:"overridable_features",number:4,type:11,label:1,typeName:".google.protobuf.FeatureSet"},{name:"fixed_features",number:5,type:11,label:1,typeName:".google.protobuf.FeatureSet"}]}]},{name:"SourceCodeInfo",field:[{name:"location",number:1,type:11,label:3,typeName:".google.protobuf.SourceCodeInfo.Location"}],nestedType:[{name:"Location",field:[{name:"path",number:1,type:5,label:3,options:{packed:!0}},{name:"span",number:2,type:5,label:3,options:{packed:!0}},{name:"leading_comments",number:3,type:9,label:1},{name:"trailing_comments",number:4,type:9,label:1},{name:"leading_detached_comments",number:6,type:9,label:3}]}],extensionRange:[{start:536e6,end:536000001}]},{name:"GeneratedCodeInfo",field:[{name:"annotation",number:1,type:11,label:3,typeName:".google.protobuf.GeneratedCodeInfo.Annotation"}],nestedType:[{name:"Annotation",field:[{name:"path",number:1,type:5,label:3,options:{packed:!0}},{name:"source_file",number:2,type:9,label:1},{name:"begin",number:3,type:5,label:1},{name:"end",number:4,type:5,label:1},{name:"semantic",number:5,type:14,label:1,typeName:".google.protobuf.GeneratedCodeInfo.Annotation.Semantic"}],enumType:[{name:"Semantic",value:[{name:"NONE",number:0},{name:"SET",number:1},{name:"ALIAS",number:2}]}]}]}],enumType:[{name:"Edition",value:[{name:"EDITION_UNKNOWN",number:0},{name:"EDITION_LEGACY",number:900},{name:"EDITION_PROTO2",number:998},{name:"EDITION_PROTO3",number:999},{name:"EDITION_2023",number:1e3},{name:"EDITION_2024",number:1001},{name:"EDITION_UNSTABLE",number:9999},{name:"EDITION_1_TEST_ONLY",number:1},{name:"EDITION_2_TEST_ONLY",number:2},{name:"EDITION_99997_TEST_ONLY",number:99997},{name:"EDITION_99998_TEST_ONLY",number:99998},{name:"EDITION_99999_TEST_ONLY",number:99999},{name:"EDITION_MAX",number:2147483647}]},{name:"SymbolVisibility",value:[{name:"VISIBILITY_UNSET",number:0},{name:"VISIBILITY_LOCAL",number:1},{name:"VISIBILITY_EXPORT",number:2}]}]}),Pf=Le(Bf,1);var As;(function(e){e[e.DECLARATION=0]="DECLARATION",e[e.UNVERIFIED=1]="UNVERIFIED"})(As||(As={}));var ks;(function(e){e[e.DOUBLE=1]="DOUBLE",e[e.FLOAT=2]="FLOAT",e[e.INT64=3]="INT64",e[e.UINT64=4]="UINT64",e[e.INT32=5]="INT32",e[e.FIXED64=6]="FIXED64",e[e.FIXED32=7]="FIXED32",e[e.BOOL=8]="BOOL",e[e.STRING=9]="STRING",e[e.GROUP=10]="GROUP",e[e.MESSAGE=11]="MESSAGE",e[e.BYTES=12]="BYTES",e[e.UINT32=13]="UINT32",e[e.ENUM=14]="ENUM",e[e.SFIXED32=15]="SFIXED32",e[e.SFIXED64=16]="SFIXED64",e[e.SINT32=17]="SINT32",e[e.SINT64=18]="SINT64"})(ks||(ks={}));var Rs;(function(e){e[e.OPTIONAL=1]="OPTIONAL",e[e.REPEATED=3]="REPEATED",e[e.REQUIRED=2]="REQUIRED"})(Rs||(Rs={}));var Os;(function(e){e[e.SPEED=1]="SPEED",e[e.CODE_SIZE=2]="CODE_SIZE",e[e.LITE_RUNTIME=3]="LITE_RUNTIME"})(Os||(Os={}));var Vs;(function(e){e[e.STRING=0]="STRING",e[e.CORD=1]="CORD",e[e.STRING_PIECE=2]="STRING_PIECE"})(Vs||(Vs={}));var Gs;(function(e){e[e.JS_NORMAL=0]="JS_NORMAL",e[e.JS_STRING=1]="JS_STRING",e[e.JS_NUMBER=2]="JS_NUMBER"})(Gs||(Gs={}));var Ls;(function(e){e[e.RETENTION_UNKNOWN=0]="RETENTION_UNKNOWN",e[e.RETENTION_RUNTIME=1]="RETENTION_RUNTIME",e[e.RETENTION_SOURCE=2]="RETENTION_SOURCE"})(Ls||(Ls={}));var Fs;(function(e){e[e.TARGET_TYPE_UNKNOWN=0]="TARGET_TYPE_UNKNOWN",e[e.TARGET_TYPE_FILE=1]="TARGET_TYPE_FILE",e[e.TARGET_TYPE_EXTENSION_RANGE=2]="TARGET_TYPE_EXTENSION_RANGE",e[e.TARGET_TYPE_MESSAGE=3]="TARGET_TYPE_MESSAGE",e[e.TARGET_TYPE_FIELD=4]="TARGET_TYPE_FIELD",e[e.TARGET_TYPE_ONEOF=5]="TARGET_TYPE_ONEOF",e[e.TARGET_TYPE_ENUM=6]="TARGET_TYPE_ENUM",e[e.TARGET_TYPE_ENUM_ENTRY=7]="TARGET_TYPE_ENUM_ENTRY",e[e.TARGET_TYPE_SERVICE=8]="TARGET_TYPE_SERVICE",e[e.TARGET_TYPE_METHOD=9]="TARGET_TYPE_METHOD"})(Fs||(Fs={}));var qr;(function(e){e[e.IDEMPOTENCY_UNKNOWN=0]="IDEMPOTENCY_UNKNOWN",e[e.NO_SIDE_EFFECTS=1]="NO_SIDE_EFFECTS",e[e.IDEMPOTENT=2]="IDEMPOTENT"})(qr||(qr={}));var Us;(function(e){e[e.DEFAULT_SYMBOL_VISIBILITY_UNKNOWN=0]="DEFAULT_SYMBOL_VISIBILITY_UNKNOWN",e[e.EXPORT_ALL=1]="EXPORT_ALL",e[e.EXPORT_TOP_LEVEL=2]="EXPORT_TOP_LEVEL",e[e.LOCAL_ALL=3]="LOCAL_ALL",e[e.STRICT=4]="STRICT"})(Us||(Us={}));var Ds;(function(e){e[e.FIELD_PRESENCE_UNKNOWN=0]="FIELD_PRESENCE_UNKNOWN",e[e.EXPLICIT=1]="EXPLICIT",e[e.IMPLICIT=2]="IMPLICIT",e[e.LEGACY_REQUIRED=3]="LEGACY_REQUIRED"})(Ds||(Ds={}));var Ws;(function(e){e[e.ENUM_TYPE_UNKNOWN=0]="ENUM_TYPE_UNKNOWN",e[e.OPEN=1]="OPEN",e[e.CLOSED=2]="CLOSED"})(Ws||(Ws={}));var Zs;(function(e){e[e.REPEATED_FIELD_ENCODING_UNKNOWN=0]="REPEATED_FIELD_ENCODING_UNKNOWN",e[e.PACKED=1]="PACKED",e[e.EXPANDED=2]="EXPANDED"})(Zs||(Zs={}));var Cs;(function(e){e[e.UTF8_VALIDATION_UNKNOWN=0]="UTF8_VALIDATION_UNKNOWN",e[e.VERIFY=2]="VERIFY",e[e.NONE=3]="NONE"})(Cs||(Cs={}));var Ms;(function(e){e[e.MESSAGE_ENCODING_UNKNOWN=0]="MESSAGE_ENCODING_UNKNOWN",e[e.LENGTH_PREFIXED=1]="LENGTH_PREFIXED",e[e.DELIMITED=2]="DELIMITED"})(Ms||(Ms={}));var Ys;(function(e){e[e.JSON_FORMAT_UNKNOWN=0]="JSON_FORMAT_UNKNOWN",e[e.ALLOW=1]="ALLOW",e[e.LEGACY_BEST_EFFORT=2]="LEGACY_BEST_EFFORT"})(Ys||(Ys={}));var Bs;(function(e){e[e.ENFORCE_NAMING_STYLE_UNKNOWN=0]="ENFORCE_NAMING_STYLE_UNKNOWN",e[e.STYLE2024=1]="STYLE2024",e[e.STYLE_LEGACY=2]="STYLE_LEGACY"})(Bs||(Bs={}));var Ps;(function(e){e[e.NONE=0]="NONE",e[e.SET=1]="SET",e[e.ALIAS=2]="ALIAS"})(Ps||(Ps={}));var Xs;(function(e){e[e.EDITION_UNKNOWN=0]="EDITION_UNKNOWN",e[e.EDITION_LEGACY=900]="EDITION_LEGACY",e[e.EDITION_PROTO2=998]="EDITION_PROTO2",e[e.EDITION_PROTO3=999]="EDITION_PROTO3",e[e.EDITION_2023=1e3]="EDITION_2023",e[e.EDITION_2024=1001]="EDITION_2024",e[e.EDITION_UNSTABLE=9999]="EDITION_UNSTABLE",e[e.EDITION_1_TEST_ONLY=1]="EDITION_1_TEST_ONLY",e[e.EDITION_2_TEST_ONLY=2]="EDITION_2_TEST_ONLY",e[e.EDITION_99997_TEST_ONLY=99997]="EDITION_99997_TEST_ONLY",e[e.EDITION_99998_TEST_ONLY=99998]="EDITION_99998_TEST_ONLY",e[e.EDITION_99999_TEST_ONLY=99999]="EDITION_99999_TEST_ONLY",e[e.EDITION_MAX=2147483647]="EDITION_MAX"})(Xs||(Xs={}));var Js;(function(e){e[e.VISIBILITY_UNSET=0]="VISIBILITY_UNSET",e[e.VISIBILITY_LOCAL=1]="VISIBILITY_LOCAL",e[e.VISIBILITY_EXPORT=2]="VISIBILITY_EXPORT"})(Js||(Js={}));const Ks={readUnknownFields:!0};function Xf(e){return e?Object.assign(Object.assign({},Ks),e):Ks}function br(e,t,n){const r=be(e,void 0,!1);return qo(r,new Ta(t),Xf(n),!1,t.byteLength),r.message}function qo(e,t,n,r,a){var s;const i=r?t.len:t.pos+a;let o,l;const u=(s=e.getUnknown())!==null&&s!==void 0?s:[];for(;t.pos0&&e.setUnknown(u)}function el(e,t,n,r,a){var s;switch(n.fieldKind){case"scalar":e.set(n,Mt(t,n.scalar));break;case"enum":const i=Mt(t,g.INT32);if(n.enum.open)e.set(n,i);else if(n.enum.values.some(l=>l.number===i))e.set(n,i);else if(a.readUnknownFields){const l=[];jr(i,l);const u=(s=e.getUnknown())!==null&&s!==void 0?s:[];u.push({no:n.number,wireType:r,data:new Uint8Array(l)}),e.setUnknown(u)}break;case"message":e.set(n,Ua(t,a,n,e.get(n)));break;case"list":Kf(t,r,e.get(n),a);break;case"map":Jf(t,e.get(n),a);break}}function Jf(e,t,n){const r=t.field();let a,s;const i=e.uint32(),o=e.pos+i;for(;e.pos{}).getFile(r.name)}const jf=vr("Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYiJgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnYKE2NvbS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaLGdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2FueXBiogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM"),zf=Le(jf,0),Hf=3,js={writeUnknownFields:!0};function $f(e){return e?Object.assign(Object.assign({},js),e):js}function tl(e,t,n){return zn(new Vo,$f(n),be(e,t)).finish()}function zn(e,t,n){var r;for(const a of n.sortedFields){if(!n.isSet(a)){if(a.presence==Hf)throw new Error(`cannot encode ${a} to binary: required field not set`);continue}nl(e,t,n,a)}if(t.writeUnknownFields)for(const{no:a,wireType:s,data:i}of(r=n.getUnknown())!==null&&r!==void 0?r:[])e.tag(a,s).raw(i);return e}function nl(e,t,n,r){var a;switch(r.fieldKind){case"scalar":case"enum":Hn(e,n.desc.typeName,r.name,(a=r.scalar)!==null&&a!==void 0?a:g.INT32,r.number,n.get(r));break;case"list":Qf(e,t,r,n.get(r));break;case"message":rl(e,t,r,n.get(r));break;case"map":for(const[s,i]of n.get(r))qf(e,t,r,s,i);break}}function Hn(e,t,n,r,a,s){al(e.tag(a,ed(r)),t,n,r,s)}function rl(e,t,n,r){n.delimitedEncoding?zn(e.tag(n.number,ee.StartGroup),t,r).tag(n.number,ee.EndGroup):zn(e.tag(n.number,ee.LengthDelimited).fork(),t,r).join()}function Qf(e,t,n,r){var a;if(n.listKind=="message"){for(const i of r)rl(e,t,n,i);return}const s=(a=n.scalar)!==null&&a!==void 0?a:g.INT32;if(n.packed){if(!r.size)return;e.tag(n.number,ee.LengthDelimited).fork();for(const i of r)al(e,n.parent.typeName,n.name,s,i);e.join();return}for(const i of r)Hn(e,n.parent.typeName,n.name,s,n.number,i)}function qf(e,t,n,r,a){var s;switch(e.tag(n.number,ee.LengthDelimited).fork(),Hn(e,n.parent.typeName,n.name,n.mapKey,1,r),n.mapKind){case"scalar":case"enum":Hn(e,n.parent.typeName,n.name,(s=n.scalar)!==null&&s!==void 0?s:g.INT32,2,a);break;case"message":zn(e.tag(2,ee.LengthDelimited).fork(),t,a).join();break}e.join()}function al(e,t,n,r,a){try{switch(r){case g.STRING:e.string(a);break;case g.BOOL:e.bool(a);break;case g.DOUBLE:e.double(a);break;case g.FLOAT:e.float(a);break;case g.INT32:e.int32(a);break;case g.INT64:e.int64(a);break;case g.UINT64:e.uint64(a);break;case g.FIXED64:e.fixed64(a);break;case g.BYTES:e.bytes(a);break;case g.FIXED32:e.fixed32(a);break;case g.SFIXED32:e.sfixed32(a);break;case g.SFIXED64:e.sfixed64(a);break;case g.SINT64:e.sint64(a);break;case g.UINT32:e.uint32(a);break;case g.SINT32:e.sint32(a);break}}catch(s){throw s instanceof Error?new Error(`cannot encode field ${t}.${n} to binary: ${s.message}`):s}}function ed(e){switch(e){case g.BYTES:case g.STRING:return ee.LengthDelimited;case g.DOUBLE:case g.FIXED64:case g.SFIXED64:return ee.Bit64;case g.FIXED32:case g.SFIXED32:case g.FLOAT:return ee.Bit32;default:return ee.Varint}}function td(e,t,n){let r=!1;return n||(n=Se(zf),r=!0),n.value=tl(e,t),n.typeUrl=ad(t.$typeName),r?n:void 0}function nd(e,t){if(e.typeUrl==="")return!1;const n=typeof t=="string"?t:t.typeName,r=sl(e.typeUrl);return n===r}function rd(e,t){if(e.typeUrl==="")return;const n=t.kind=="message"?t:t.getMessage(sl(e.typeUrl));if(!(!n||!nd(e,n)))return br(n,e.value)}function ad(e){return`type.googleapis.com/${e}`}function sl(e){const t=e.lastIndexOf("/"),n=t>=0?e.substring(t+1):e;if(!n.length)throw new Error(`invalid type url: ${e}`);return n}const Da=vr("Chxnb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvEg9nb29nbGUucHJvdG9idWYihAEKBlN0cnVjdBIzCgZmaWVsZHMYASADKAsyIy5nb29nbGUucHJvdG9idWYuU3RydWN0LkZpZWxkc0VudHJ5GkUKC0ZpZWxkc0VudHJ5EgsKA2tleRgBIAEoCRIlCgV2YWx1ZRgCIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZToCOAEi6gEKBVZhbHVlEjAKCm51bGxfdmFsdWUYASABKA4yGi5nb29nbGUucHJvdG9idWYuTnVsbFZhbHVlSAASFgoMbnVtYmVyX3ZhbHVlGAIgASgBSAASFgoMc3RyaW5nX3ZhbHVlGAMgASgJSAASFAoKYm9vbF92YWx1ZRgEIAEoCEgAEi8KDHN0cnVjdF92YWx1ZRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9WQUxVRRAAQn8KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAFaL2dvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3N0cnVjdHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM"),sd=Le(Da,0),il=Le(Da,1),id=Le(Da,2);var ea;(function(e){e[e.NULL_VALUE=0]="NULL_VALUE"})(ea||(ea={}));function od(e,t){ol(t,e);const n=ud(e.$unknown,t),[r,a,s]=gr(t);for(const i of n)el(r,new Ta(i.data),a,i.wireType,{readUnknownFields:!0});return s()}function ld(e,t,n){var r;ol(t,e);const a=((r=e.$unknown)!==null&&r!==void 0?r:[]).filter(u=>u.no!==t.number),[s,i]=gr(t,n),o=new Vo;nl(o,{writeUnknownFields:!0},s,i);const l=new Ta(o.finish());for(;l.pos=0;--n)if(e[n].no==t.number)return[e[n]];return[]}return e.filter(n=>n.no===t.number)}function gr(e,t){const n=e.typeName,r=Object.assign(Object.assign({},e),{kind:"field",parent:e.extendee,localName:n}),a=Object.assign(Object.assign({},e.extendee),{fields:[r],members:[r],oneofs:[]}),s=Se(a,t!==void 0?{[n]:t}:void 0);return[be(a,s),r,()=>{const i=s[n];if(i===void 0){const o=e.message;return xn(o)?Wt(o.fields[0].scalar,o.fields[0].longAsString):Se(o)}return i}]}function ol(e,t){if(e.extendee.typeName!=t.$typeName)throw new Error(`extension ${e.typeName} can only be applied to message ${e.extendee.typeName}`)}function cd(e,t,n,r){return t.$typeName!=e.typeName||n.$typeName!=e.typeName?!1:t===n?!0:Bn(be(e,t),be(e,n),r)}function Bn(e,t,n){e.desc.typeName;for(const r of e.fields)if(!fd(r,e,t,n))return!1;return!0}function fd(e,t,n,r){if(!t.isSet(e)&&!n.isSet(e))return!0;if(!t.isSet(e)||!n.isSet(e))return!1;switch(e.fieldKind){case"scalar":return Ar(e.scalar,t.get(e),n.get(e));case"enum":return t.get(e)===n.get(e);case"message":return Bn(t.get(e),n.get(e),r);case"map":{const a=t.get(e),s=n.get(e),i=[];for(const o of a.keys()){if(!s.has(o))return!1;i.push(o)}for(const o of s.keys())if(!a.has(o))return!1;for(const o of i){const l=a.get(o),u=s.get(o);if(l!==u)switch(e.mapKind){case"enum":return!1;case"message":if(!Bn(l,u,r))return!1;break;case"scalar":if(!Ar(e.scalar,l,u))return!1;break}}break}case"list":{const a=t.get(e),s=n.get(e);if(a.size!=s.size)return!1;for(let i=0;i0?r:void 0}function hd(e,t){const n=e.field(),r=[];switch(n.listKind){case"scalar":for(const a of e)r.push(hr(n,a));break;case"enum":for(const a of e)r.push(Wa(n.enum,a,t.enumAsInteger));break;case"message":for(const a of e)r.push(Sn(a,t));break}return t.alwaysEmitImplicit||r.length>0?r:void 0}function Wa(e,t,n){var r;if(typeof t!="number")throw new Error(`cannot encode ${e} to JSON: expected number, got ${ce(t)}`);if(e.typeName=="google.protobuf.NullValue")return null;if(n)return t;const a=e.value[t];return(r=a?.name)!==null&&r!==void 0?r:t}function hr(e,t){var n,r,a,s,i,o;switch(e.scalar){case g.INT32:case g.SFIXED32:case g.SINT32:case g.FIXED32:case g.UINT32:if(typeof t!="number")throw new Error(`cannot encode ${e} to JSON: ${(n=bt(e,t))===null||n===void 0?void 0:n.message}`);return t;case g.FLOAT:case g.DOUBLE:if(typeof t!="number")throw new Error(`cannot encode ${e} to JSON: ${(r=bt(e,t))===null||r===void 0?void 0:r.message}`);return Number.isNaN(t)?"NaN":t===Number.POSITIVE_INFINITY?"Infinity":t===Number.NEGATIVE_INFINITY?"-Infinity":t;case g.STRING:if(typeof t!="string")throw new Error(`cannot encode ${e} to JSON: ${(a=bt(e,t))===null||a===void 0?void 0:a.message}`);return t;case g.BOOL:if(typeof t!="boolean")throw new Error(`cannot encode ${e} to JSON: ${(s=bt(e,t))===null||s===void 0?void 0:s.message}`);return t;case g.UINT64:case g.FIXED64:case g.INT64:case g.SFIXED64:case g.SINT64:if(typeof t!="bigint"&&typeof t!="string")throw new Error(`cannot encode ${e} to JSON: ${(i=bt(e,t))===null||i===void 0?void 0:i.message}`);return t.toString();case g.BYTES:if(t instanceof Uint8Array)return Po(t);throw new Error(`cannot encode ${e} to JSON: ${(o=bt(e,t))===null||o===void 0?void 0:o.message}`)}}function yd(e,t){return t.useProtoFieldName?e.name:e.jsonName}function _d(e,t){if(e.desc.typeName.startsWith("google.protobuf."))switch(e.desc.typeName){case"google.protobuf.Any":return Ed(e.message,t);case"google.protobuf.Timestamp":return Id(e.message);case"google.protobuf.Duration":return Nd(e.message);case"google.protobuf.FieldMask":return wd(e.message);case"google.protobuf.Struct":return ll(e.message);case"google.protobuf.Value":return Za(e.message);case"google.protobuf.ListValue":return ul(e.message);default:if(xn(e.desc)){const n=e.desc.fields[0];return hr(n,e.get(n))}return}}function Ed(e,t){if(e.typeUrl==="")return{};const{registry:n}=t;let r,a;if(n&&(r=rd(e,n),r&&(a=n.getMessage(r.$typeName))),!a||!r)throw new Error(`cannot encode message ${e.$typeName} to JSON: "${e.typeUrl}" is not in the type registry`);let s=Sn(be(a,r),t);return(a.typeName.startsWith("google.protobuf.")||s===null||Array.isArray(s)||typeof s!="object")&&(s={value:s}),s["@type"]=e.typeUrl,s}function Nd(e){const t=Number(e.seconds),n=e.nanos;if(t>315576e6||t<-315576e6)throw new Error(`cannot encode message ${e.$typeName} to JSON: value out of range`);if(t>0&&n<0||t<0&&n>0)throw new Error(`cannot encode message ${e.$typeName} to JSON: nanos sign must match seconds sign`);let r=e.seconds.toString();if(n!==0){let a=Math.abs(n).toString();a="0".repeat(9-a.length)+a,a.substring(3)==="000000"?a=a.substring(0,3):a.substring(6)==="000"&&(a=a.substring(0,6)),r+="."+a,n<0&&t==0&&(r="-"+r)}return r+"s"}function wd(e){return e.paths.map(t=>{if(Jo(Zt(t))!==t)throw new Error(`cannot encode message ${e.$typeName} to JSON: lowerCamelCase of path name "${t}" is irreversible`);return Zt(t)}).join(",")}function ll(e){const t={};for(const[n,r]of Object.entries(e.fields))t[n]=Za(r);return t}function Za(e){switch(e.kind.case){case"nullValue":return null;case"numberValue":if(!Number.isFinite(e.kind.value))throw new Error(`${e.$typeName} cannot be NaN or Infinity`);return e.kind.value;case"boolValue":return e.kind.value;case"stringValue":return e.kind.value;case"structValue":return ll(e.kind.value);case"listValue":return ul(e.kind.value);default:throw new Error(`${e.$typeName} must have a value`)}}function ul(e){return e.values.map(Za)}function Id(e){const t=Number(e.seconds)*1e3;if(tDate.parse("9999-12-31T23:59:59Z"))throw new Error(`cannot encode message ${e.$typeName} to JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);if(e.nanos<0)throw new Error(`cannot encode message ${e.$typeName} to JSON: nanos must not be negative`);if(e.nanos>999999999)throw new Error(`cannot encode message ${e.$typeName} to JSON: nanos must not be greater than 99999999`);let n="Z";if(e.nanos>0){const r=(e.nanos+1e9).toString().substring(1);r.substring(3)==="000000"?n="."+r.substring(0,3)+"Z":r.substring(6)==="000"?n="."+r.substring(0,6)+"Z":n="."+r+"Z"}return new Date(t).toISOString().replace(".000Z",n)}const $s={ignoreUnknownFields:!1};function xd(e){return e?Object.assign(Object.assign({},$s),e):$s}function Sd(e,t,n){return cl(e,Ld(t,e.typeName),n)}function cl(e,t,n){const r=be(e);try{dn(r,t,xd(n))}catch(a){throw rf(a)?new Error(`cannot decode ${a.field()} from JSON: ${a.message}`,{cause:a}):a}return r.message}const Ur=new WeakMap;function Td(e,t){var n;if(!Ur.has(e)){const r=new Map;for(const a of e.fields)r.set(a.name,a).set(a.jsonName,a);Ur.set(e,r)}return(n=Ur.get(e))===null||n===void 0?void 0:n.get(t)}function dn(e,t,n){var r;if(Fd(e,t,n))return;if(t==null||Array.isArray(t)||typeof t!="object")throw new Error(`cannot decode ${e.desc} from JSON: ${ce(t)}`);const a=new Map;for(const[s,i]of Object.entries(t)){const o=Td(e.desc,s);if(o){if(o.oneof){if(i===null&&o.fieldKind=="scalar")continue;const l=a.get(o.oneof);if(l!==void 0)throw new xe(o.oneof,`oneof set multiple times by ${l.name} and ${o.name}`);a.set(o.oneof,o)}Qs(e,o,i,n)}else{let l;if(s.startsWith("[")&&s.endsWith("]")&&(l=(r=n.registry)===null||r===void 0?void 0:r.getExtension(s.substring(1,s.length-1)))&&l.extendee.typeName===e.desc.typeName){const[u,c,m]=gr(l);Qs(u,c,i,n),ld(e.message,l,m())}if(!l&&!n.ignoreUnknownFields)throw new Error(`cannot decode ${e.desc} from JSON: key "${s}" is unknown`)}}}function Qs(e,t,n,r){switch(t.fieldKind){case"scalar":Vd(e,t,n);break;case"enum":Od(e,t,n,r);break;case"message":Rd(e,t,n,r);break;case"list":kd(e.get(t),n,r);break;case"map":Ad(e.get(t),n,r);break}}function fl(e,t,n){if(e.scalar&&t!==null)return Ca(e,t);if(e.message&&!$n(e,t)){const r=be(e.message);return dn(r,t,n),r}if(e.enum&&!$n(e,t))return dl(e.enum,t,n.ignoreUnknownFields);throw new xe(e,`${e.fieldKind==="list"?"list item":"map value"} must not be null`)}function Ad(e,t,n){if(t===null)return;const r=e.field();if(typeof t!="object"||Array.isArray(t))throw new xe(r,"expected object, got "+ce(t));for(const[a,s]of Object.entries(t)){const i=Gd(r.mapKey,a),o=fl(r,s,n);o!==yr&&e.set(i,o)}}function kd(e,t,n){if(t===null)return;const r=e.field();if(!Array.isArray(t))throw new xe(r,"expected Array, got "+ce(t));for(const a of t){const s=fl(r,a,n);s!==yr&&e.add(s)}}function Rd(e,t,n,r){if($n(t,n)){e.clear(t);return}const a=e.isSet(t)?e.get(t):be(t.message);dn(a,n,r),e.set(t,a)}function Od(e,t,n,r){if($n(t,n)){e.clear(t);return}const a=dl(t.enum,n,r.ignoreUnknownFields);a!==yr&&e.set(t,a)}function Vd(e,t,n){n===null?e.clear(t):e.set(t,Ca(t,n))}function $n(e,t){var n,r;return t===null&&((n=e.message)===null||n===void 0?void 0:n.typeName)!="google.protobuf.Value"&&((r=e.enum)===null||r===void 0?void 0:r.typeName)!="google.protobuf.NullValue"}const yr=Symbol();function dl(e,t,n){if(t===null)return e.values[0].number;switch(typeof t){case"number":if(Number.isInteger(t))return t;break;case"string":const r=e.values.find(a=>a.name===t);if(r!==void 0)return r.number;if(n)return yr;break}throw new Error(`cannot decode ${e} from JSON: ${ce(t)}`)}function Ca(e,t){switch(e.scalar){case g.DOUBLE:case g.FLOAT:if(t==="NaN")return NaN;if(t==="Infinity")return Number.POSITIVE_INFINITY;if(t==="-Infinity")return Number.NEGATIVE_INFINITY;if(typeof t=="number"){if(Number.isNaN(t))throw new xe(e,"unexpected NaN number");if(!Number.isFinite(t))throw new xe(e,"unexpected infinite number");break}if(typeof t=="string"){if(t===""||t.trim().length!==t.length)break;const n=Number(t);if(!Number.isFinite(n))break;return n}break;case g.INT32:case g.FIXED32:case g.SFIXED32:case g.SINT32:case g.UINT32:return ml(t);case g.BYTES:if(typeof t=="string"){if(t==="")return new Uint8Array(0);try{return Ga(t)}catch(n){const r=n instanceof Error?n.message:String(n);throw new xe(e,r)}}break}return t}function Gd(e,t){switch(e){case g.BOOL:switch(t){case"true":return!0;case"false":return!1}return t;case g.INT32:case g.FIXED32:case g.UINT32:case g.SFIXED32:case g.SINT32:return ml(t);default:return t}}function ml(e){if(typeof e=="string"){if(e===""||e.trim().length!==e.length)return e;const t=Number(e);return Number.isNaN(t)?e:t}return e}function Ld(e,t){try{return JSON.parse(e)}catch(n){const r=n instanceof Error?n.message:String(n);throw new Error(`cannot decode message ${t} from JSON: ${r}`,{cause:n})}}function Fd(e,t,n){if(!e.desc.typeName.startsWith("google.protobuf."))return!1;switch(e.desc.typeName){case"google.protobuf.Any":return Ud(e.message,t,n),!0;case"google.protobuf.Timestamp":return Dd(e.message,t),!0;case"google.protobuf.Duration":return Wd(e.message,t),!0;case"google.protobuf.FieldMask":return Zd(e.message,t),!0;case"google.protobuf.Struct":return pl(e.message,t),!0;case"google.protobuf.Value":return Ma(e.message,t),!0;case"google.protobuf.ListValue":return bl(e.message,t),!0;default:if(xn(e.desc)){const r=e.desc.fields[0];return t===null?e.clear(r):e.set(r,Ca(r,t)),!0}return!1}}function Ud(e,t,n){var r;if(t===null||Array.isArray(t)||typeof t!="object")throw new Error(`cannot decode message ${e.$typeName} from JSON: expected object but got ${ce(t)}`);if(Object.keys(t).length==0)return;const a=t["@type"];if(typeof a!="string"||a=="")throw new Error(`cannot decode message ${e.$typeName} from JSON: "@type" is empty`);const s=a.includes("/")?a.substring(a.lastIndexOf("/")+1):a;if(!s.length)throw new Error(`cannot decode message ${e.$typeName} from JSON: "@type" is invalid`);const i=(r=n.registry)===null||r===void 0?void 0:r.getMessage(s);if(!i)throw new Error(`cannot decode message ${e.$typeName} from JSON: ${a} is not in the type registry`);const o=be(i);if(s.startsWith("google.protobuf.")&&Object.prototype.hasOwnProperty.call(t,"value")){const l=t.value;dn(o,l,n)}else{const l=Object.assign({},t);delete l["@type"],dn(o,l,n)}td(o.desc,o.message,e)}function Dd(e,t){if(typeof t!="string")throw new Error(`cannot decode message ${e.$typeName} from JSON: ${ce(t)}`);const n=t.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\.([0-9]{1,9}))?(?:Z|([+-][0-9][0-9]:[0-9][0-9]))$/);if(!n)throw new Error(`cannot decode message ${e.$typeName} from JSON: invalid RFC 3339 string`);const r=Date.parse(n[1]+"-"+n[2]+"-"+n[3]+"T"+n[4]+":"+n[5]+":"+n[6]+(n[8]?n[8]:"Z"));if(Number.isNaN(r))throw new Error(`cannot decode message ${e.$typeName} from JSON: invalid RFC 3339 string`);if(rDate.parse("9999-12-31T23:59:59Z"))throw new Error(`cannot decode message ${e.$typeName} from JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);e.seconds=z.parse(r/1e3),e.nanos=0,n[7]&&(e.nanos=parseInt("1"+n[7]+"0".repeat(9-n[7].length))-1e9)}function Wd(e,t){if(typeof t!="string")throw new Error(`cannot decode message ${e.$typeName} from JSON: ${ce(t)}`);const n=t.match(/^(-?[0-9]+)(?:\.([0-9]+))?s/);if(n===null)throw new Error(`cannot decode message ${e.$typeName} from JSON: ${ce(t)}`);const r=Number(n[1]);if(r>315576e6||r<-315576e6)throw new Error(`cannot decode message ${e.$typeName} from JSON: ${ce(t)}`);if(e.seconds=z.parse(r),typeof n[2]!="string")return;const a=n[2]+"0".repeat(9-n[2].length);e.nanos=parseInt(a),(r<0||Object.is(r,-0))&&(e.nanos=-e.nanos)}function Zd(e,t){if(typeof t!="string")throw new Error(`cannot decode message ${e.$typeName} from JSON: ${ce(t)}`);t!==""&&(e.paths=t.split(",").map(n=>{if(n.includes("_"))throw new Error(`cannot decode message ${e.$typeName} from JSON: path names must be lowerCamelCase`);return Jo(n)}))}function pl(e,t){if(typeof t!="object"||t==null||Array.isArray(t))throw new Error(`cannot decode message ${e.$typeName} from JSON ${ce(t)}`);for(const[n,r]of Object.entries(t)){const a=Se(il);Ma(a,r),e.fields[n]=a}}function Ma(e,t){switch(typeof t){case"number":e.kind={case:"numberValue",value:t};break;case"string":e.kind={case:"stringValue",value:t};break;case"boolean":e.kind={case:"boolValue",value:t};break;case"object":if(t===null)e.kind={case:"nullValue",value:ea.NULL_VALUE};else if(Array.isArray(t)){const n=Se(id);bl(n,t),e.kind={case:"listValue",value:n}}else{const n=Se(sd);pl(n,t),e.kind={case:"structValue",value:n}}break;default:throw new Error(`cannot decode message ${e.$typeName} from JSON ${ce(t)}`)}return e}function bl(e,t){if(!Array.isArray(t))throw new Error(`cannot decode message ${e.$typeName} from JSON ${ce(t)}`);for(const n of t){const r=Se(il);Ma(r,n),e.values.push(r)}}function ta(e){const t=J[e];return typeof t!="string"?e.toString():t[0].toLowerCase()+t.substring(1).replace(/[A-Z]/g,n=>"_"+n.toLowerCase())}let Vn;function Cd(e){if(!Vn){Vn={};for(const t of Object.values(J))typeof t!="string"&&(Vn[ta(t)]=t)}return Vn[e]}class re extends Error{constructor(t,n=J.Unknown,r,a,s){super(Md(t,n)),this.name="ConnectError",Object.setPrototypeOf(this,new.target.prototype),this.rawMessage=t,this.code=n,this.metadata=new Headers(r??{}),this.details=a??[],this.cause=s}static from(t,n=J.Unknown){return t instanceof re?t:t instanceof Error?t.name=="AbortError"||t.name=="TimeoutError"?new re(t.message,J.Canceled):new re(t.message,n,void 0,void 0,t):new re(String(t),n,void 0,void 0,t)}static[Symbol.hasInstance](t){return t instanceof Error?Object.getPrototypeOf(t)===re.prototype?!0:t.name==="ConnectError"&&"code"in t&&typeof t.code=="number"&&"metadata"in t&&"details"in t&&Array.isArray(t.details)&&"rawMessage"in t&&typeof t.rawMessage=="string"&&"cause"in t:!1}findDetails(t){const n=t.kind==="message"?{getMessage:a=>a===t.typeName?t:void 0}:t,r=[];for(const a of this.details){if("desc"in a){n.getMessage(a.desc.typeName)&&r.push(Se(a.desc,a.value));continue}const s=n.getMessage(a.type);if(s)try{r.push(br(s,a.value))}catch{}}return r}}function Md(e,t){return e.length?`[${ta(t)}] ${e}`:`[${ta(t)}]`}function Yd(...e){const t=new Headers;for(const n of e)n.forEach((r,a)=>{t.append(a,r)});return t}function Bd(e,t){const n={};for(const r of e.methods){const a=t(r);a!=null&&(n[r.localName]=a)}return n}const qs=1;function Pd(e,t,n=!1){if(t>e){let r=`message size is larger than configured readMaxBytes ${e}`;throw n&&(r=`message size ${t} is larger than configured readMaxBytes ${e}`),new re(r,J.ResourceExhausted)}}function Xd(e){return new Jd(e)}class Jd{constructor(t){this.readMaxBytes=t,this.header=new Uint8Array(5),this.headerView=new DataView(this.header.buffer),this.buf=[]}get byteLength(){return this.buf.reduce((t,n)=>t+n.byteLength,0)}decode(t){this.buf.push(t);const n=[];for(;;){let r=this.pop();if(!r)break;n.push(r)}return n}pop(){if(!(!this.env&&(this.env=this.head(),!this.env))&&this.cons(this.env.data)){const t=this.env;return this.env=void 0,t}}head(){if(!this.cons(this.header))return;const t=this.headerView.getUint8(0),n=this.headerView.getUint32(1);return Pd(this.readMaxBytes,n,!0),{flags:t,data:new Uint8Array(n)}}cons(t){const n=t.byteLength;if(this.byteLengthn-r?(t.set(a.subarray(0,n-r),r),this.buf.unshift(a.subarray(n-r)),r+=n-r):(t.set(a,r),r+=a.byteLength)}return!0}}function Kd(e){let t;const n=Xd(4294967295);return new ReadableStream({start(){t=e.getReader()},async pull(r){let a=!1;for(;!a;){const s=await t.read();if(s.done)n.byteLength>0&&r.error(new re("protocol error: incomplete envelope",J.InvalidArgument)),r.close();else for(const i of n.decode(s.value))r.enqueue(i),a=!0}}})}function jd(e,t){const n=new Uint8Array(t.length+5);n.set(t,5);const r=new DataView(n.buffer,n.byteOffset,n.byteLength);return r.setUint8(0,e),r.setUint32(1,t.length),n}var zd=function(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],n;return t?t.call(e):(e=typeof __values=="function"?__values(e):e[Symbol.iterator](),n={},r("next"),r("throw"),r("return"),n[Symbol.asyncIterator]=function(){return this},n);function r(s){n[s]=e[s]&&function(i){return new Promise(function(o,l){i=e[s](i),a(o,l,i.done,i.value)})}}function a(s,i,o,l){Promise.resolve(l).then(function(u){s({value:u,done:o})},i)}},mn=function(e){return this instanceof mn?(this.v=e,this):new mn(e)},Hd=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r=n.apply(e,t||[]),a,s=[];return a=Object.create((typeof AsyncIterator=="function"?AsyncIterator:Object).prototype),o("next"),o("throw"),o("return",i),a[Symbol.asyncIterator]=function(){return this},a;function i(f){return function(b){return Promise.resolve(b).then(f,m)}}function o(f,b){r[f]&&(a[f]=function(h){return new Promise(function(v,N){s.push([f,h,v,N])>1||l(f,h)})},b&&(a[f]=b(a[f])))}function l(f,b){try{u(r[f](b))}catch(h){p(s[0][3],h)}}function u(f){f.value instanceof mn?Promise.resolve(f.value.v).then(c,m):p(s[0][2],f)}function c(f){l("next",f)}function m(f){l("throw",f)}function p(f,b){f(b),s.shift(),s.length&&l(s[0][0],s[0][1])}},$d=function(e){var t,n;return t={},r("next"),r("throw",function(a){throw a}),r("return"),t[Symbol.iterator]=function(){return this},t;function r(a,s){t[a]=e[a]?function(i){return(n=!n)?{value:mn(e[a](i)),done:!1}:s?s(i):i}:s}};function Qd(e){return Hd(this,arguments,function*(){yield mn(yield*$d(zd(e)))})}var vl=function(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],n;return t?t.call(e):(e=typeof __values=="function"?__values(e):e[Symbol.iterator](),n={},r("next"),r("throw"),r("return"),n[Symbol.asyncIterator]=function(){return this},n);function r(s){n[s]=e[s]&&function(i){return new Promise(function(o,l){i=e[s](i),a(o,l,i.done,i.value)})}}function a(s,i,o,l){Promise.resolve(l).then(function(u){s({value:u,done:o})},i)}},Yt=function(e){return this instanceof Yt?(this.v=e,this):new Yt(e)},qd=function(e){var t,n;return t={},r("next"),r("throw",function(a){throw a}),r("return"),t[Symbol.iterator]=function(){return this},t;function r(a,s){t[a]=e[a]?function(i){return(n=!n)?{value:Yt(e[a](i)),done:!1}:s?s(i):i}:s}},em=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r=n.apply(e,t||[]),a,s=[];return a=Object.create((typeof AsyncIterator=="function"?AsyncIterator:Object).prototype),o("next"),o("throw"),o("return",i),a[Symbol.asyncIterator]=function(){return this},a;function i(f){return function(b){return Promise.resolve(b).then(f,m)}}function o(f,b){r[f]&&(a[f]=function(h){return new Promise(function(v,N){s.push([f,h,v,N])>1||l(f,h)})},b&&(a[f]=b(a[f])))}function l(f,b){try{u(r[f](b))}catch(h){p(s[0][3],h)}}function u(f){f.value instanceof Yt?Promise.resolve(f.value.v).then(c,m):p(s[0][2],f)}function c(f){l("next",f)}function m(f){l("throw",f)}function p(f,b){f(b),s.shift(),s.length&&l(s[0][0],s[0][1])}};function gl(e,t){return Bd(e,n=>{switch(n.methodKind){case"unary":return tm(t,n);case"server_streaming":return nm(t,n);case"client_streaming":return rm(t,n);case"bidi_streaming":return am(t,n);default:return null}})}function tm(e,t){return async(n,r)=>{var a,s;const i=await e.unary(t,r?.signal,r?.timeoutMs,r?.headers,n,r?.contextValues);return(a=r?.onHeader)===null||a===void 0||a.call(r,i.header),(s=r?.onTrailer)===null||s===void 0||s.call(r,i.trailer),i.message}}function nm(e,t){return(n,r)=>hl(e.stream(t,r?.signal,r?.timeoutMs,r?.headers,Qd([n]),r?.contextValues),r)}function rm(e,t){return async(n,r)=>{var a,s,i,o,l,u;const c=await e.stream(t,r?.signal,r?.timeoutMs,r?.headers,n,r?.contextValues);(l=r?.onHeader)===null||l===void 0||l.call(r,c.header);let m,p=0;try{for(var f=!0,b=vl(c.message),h;h=await b.next(),a=h.done,!a;f=!0)o=h.value,f=!1,m=o,p++}catch(v){s={error:v}}finally{try{!f&&!a&&(i=b.return)&&await i.call(b)}finally{if(s)throw s.error}}if(!m)throw new re("protocol error: missing response message",J.Unimplemented);if(p>1)throw new re("protocol error: received extra messages for client streaming method",J.Unimplemented);return(u=r?.onTrailer)===null||u===void 0||u.call(r,c.trailer),m}}function am(e,t){return(n,r)=>hl(e.stream(t,r?.signal,r?.timeoutMs,r?.headers,n,r?.contextValues),r)}function hl(e,t){const n=(function(){return em(this,arguments,function*(){var r,a;const s=yield Yt(e);(r=t?.onHeader)===null||r===void 0||r.call(t,s.header),yield Yt(yield*qd(vl(s.message))),(a=t?.onTrailer)===null||a===void 0||a.call(t,s.trailer)})})()[Symbol.asyncIterator]();return{[Symbol.asyncIterator]:()=>({next:()=>n.next()})}}function sm(...e){const t=new AbortController,n=e.filter(a=>a!==void 0).concat(t.signal);for(const a of n){if(a.aborted){r.apply(a);break}a.addEventListener("abort",r)}function r(){t.signal.aborted||t.abort(yl(this));for(const a of n)a.removeEventListener("abort",r)}return t}function im(e){const t=new AbortController,n=()=>{t.abort(new re("the operation timed out",J.DeadlineExceeded))};let r;return e!==void 0&&(e<=0?n():r=setTimeout(n,e)),{signal:t.signal,cleanup:()=>clearTimeout(r)}}function yl(e){if(!e.aborted)return;if(e.reason!==void 0)return e.reason;const t=new Error("This operation was aborted");return t.name="AbortError",t}function ei(){return{get(e){return e.id in this?this[e.id]:e.defaultValue},set(e,t){return this[e.id]=t,this},delete(e){return delete this[e.id],this}}}function _l(e,t,...n){if(n.length>0)throw new Error;return e.services[t]}function ti(e,t){return e.toString().replace(/\/?$/,`/${t.parent.typeName}/${t.name}`)}function El(e,t){return Se(e,t)}function om(e,t){function n(r){return r.done===!0?r:{done:r.done,value:El(e,r.value)}}return{[Symbol.asyncIterator](){const r=t[Symbol.asyncIterator](),a={next:()=>r.next().then(n)};return r.throw!==void 0&&(a.throw=s=>r.throw(s).then(n)),r.return!==void 0&&(a.return=s=>r.return(s).then(n)),a}}}function Nl(e,t){if(!t)return e;for(const n of t.concat().reverse())e=n(e);return e}function wl(e){var t;const n=Object.assign({},e);return(t=n.ignoreUnknownFields)!==null&&t!==void 0||(n.ignoreUnknownFields=!0),n}function ni(e,t,n,r){const a=t?ri(e.input,r):ai(e.input,n);return{parse:(t?ri(e.output,r):ai(e.output,n)).parse,serialize:a.serialize}}function ri(e,t){return{parse(n){try{return br(e,n,t)}catch(r){const a=r instanceof Error?r.message:String(r);throw new re(`parse binary: ${a}`,J.Internal)}},serialize(n){try{return tl(e,n,t)}catch(r){const a=r instanceof Error?r.message:String(r);throw new re(`serialize binary: ${a}`,J.Internal)}}}}function ai(e,t){var n,r;const a=(n=t?.textEncoder)!==null&&n!==void 0?n:new TextEncoder,s=(r=t?.textDecoder)!==null&&r!==void 0?r:new TextDecoder,i=wl(t);return{parse(o){try{const l=s.decode(o);return Sd(e,l,i)}catch(l){throw re.from(l,J.InvalidArgument)}},serialize(o){try{const l=vd(e,o,i);return a.encode(l)}catch(l){throw re.from(l,J.Internal)}}}}const lm=/^application\/(connect\+)?(?:(json)(?:; ?charset=utf-?8)?|(proto))$/i,um="application/proto",cm="application/json",fm="application/connect+proto",dm="application/connect+json";function mm(e){const t=e?.match(lm);if(!t)return;const n=!!t[1],r=!!t[3];return{stream:n,binary:r}}function Il(e,t,n){var r;if(t&&new Headers(t).forEach((o,l)=>n.metadata.append(l,o)),typeof e!="object"||e==null||Array.isArray(e))throw n;let a=n.code;"code"in e&&typeof e.code=="string"&&(a=(r=Cd(e.code))!==null&&r!==void 0?r:a);const s=e.message;if(s!=null&&typeof s!="string")throw n;const i=new re(s??"",a,t);if("details"in e&&Array.isArray(e.details))for(const o of e.details){if(o===null||typeof o!="object"||Array.isArray(o)||typeof o.type!="string"||typeof o.value!="string")throw n;try{i.details.push({type:o.type,value:Ga(o.value),debug:o.debug})}catch{throw n}}return i}const si=2;function pm(e){const t=new re("invalid end stream",J.Unknown);let n;try{n=JSON.parse(typeof e=="string"?e:new TextDecoder().decode(e))}catch{throw t}if(typeof n!="object"||n==null||Array.isArray(n))throw t;const r=new Headers;if("metadata"in n){if(typeof n.metadata!="object"||n.metadata==null||Array.isArray(n.metadata))throw t;for(const[s,i]of Object.entries(n.metadata)){if(!Array.isArray(i)||i.some(o=>typeof o!="string"))throw t;for(const o of i)r.append(s,o)}}const a="error"in n&&n.error!=null?Il(n.error,r,t):void 0;return{metadata:r,error:a}}const Qn="Content-Type",bm="Content-Length",ii="Content-Encoding",vm="Accept-Encoding",gm="Connect-Timeout-Ms",xl="Connect-Protocol-Version",hm="User-Agent";function ym(e){switch(e){case 400:return J.Internal;case 401:return J.Unauthenticated;case 403:return J.PermissionDenied;case 404:return J.Unimplemented;case 429:return J.Unavailable;case 502:return J.Unavailable;case 503:return J.Unavailable;case 504:return J.Unavailable;default:return J.Unknown}}function oi(e){const t=new Headers,n=new Headers;return e.forEach((r,a)=>{a.toLowerCase().startsWith("trailer-")?n.append(a.substring(8),r):t.append(a,r)}),[t,n]}const Sl="1";function li(e,t,n,r,a){const s=new Headers(r??{});return n!==void 0&&s.set(gm,`${n}`),s.set(Qn,e=="unary"?t?um:cm:t?fm:dm),s.set(xl,Sl),s.has(hm),s}function ui(e,t,n,r){const a=r.get(Qn),s=mm(a);if(n!==200){const o=new re(`HTTP ${n}`,ym(n),r);if(e=="unary"&&s&&!s.binary)return{isUnaryError:!0,unaryError:o};throw o}const i={binary:t,stream:e!=="unary"};if(s?.binary!==i.binary||s.stream!==i.stream)throw new re(`unsupported content type ${a}`,s===void 0?J.Unknown:J.Internal,r);return{isUnaryError:!1}}const ci="application/";function _m(e,t){return t?Po(e,"url"):encodeURIComponent(new TextDecoder().decode(e))}function Em(e,t,n){let r=`?connect=v${Sl}`;const a=e.header.get(Qn);a?.indexOf(ci)===0&&(r+="&encoding="+encodeURIComponent(a.slice(ci.length)));const s=e.header.get(ii);s!==null&&s!=="identity"&&(r+="&compression="+encodeURIComponent(s),n=!0),n&&(r+="&base64=1"),r+="&message="+_m(t,n);const i=e.url+r,o=new Headers(e.header);for(const l of[xl,Qn,bm,ii,vm])o.delete(l);return Object.assign(Object.assign({},e),{requestMethod:"GET",url:i,header:o})}function Nm(e){const t=Nl(e.next,e.interceptors),[n,r,a]=Tl(e),s=Object.assign(Object.assign({},e.req),{message:El(e.req.method.input,e.req.message),signal:n});return t(s).then(i=>(a(),i),r)}function wm(e){const t=Nl(e.next,e.interceptors),[n,r,a]=Tl(e),s=Object.assign(Object.assign({},e.req),{message:om(e.req.method.input,e.req.message),signal:n});let i=!1;return n.addEventListener("abort",function(){var o,l;const u=e.req.message[Symbol.asyncIterator]();i||(o=u.throw)===null||o===void 0||o.call(u,this.reason).catch(()=>{}),(l=u.return)===null||l===void 0||l.call(u).catch(()=>{})}),t(s).then(o=>Object.assign(Object.assign({},o),{message:{[Symbol.asyncIterator](){const l=o.message[Symbol.asyncIterator]();return{next(){return l.next().then(u=>(u.done==!0&&(i=!0,a()),u),r)}}}}}),r)}function Tl(e){const{signal:t,cleanup:n}=im(e.timeoutMs),r=sm(e.signal,t);return[r.signal,function(s){const i=re.from(t.aborted?yl(t):s);return r.abort(i),n(),Promise.reject(i)},function(){n(),r.abort()}]}function Im(){try{new Headers}catch{throw new Error("connect-web requires the fetch API. Are you running on an old version of Node.js? Node.js is not supported in Connect for Web - please stay tuned for Connect for Node.")}}var pn=function(e){return this instanceof pn?(this.v=e,this):new pn(e)},xm=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r=n.apply(e,t||[]),a,s=[];return a=Object.create((typeof AsyncIterator=="function"?AsyncIterator:Object).prototype),o("next"),o("throw"),o("return",i),a[Symbol.asyncIterator]=function(){return this},a;function i(f){return function(b){return Promise.resolve(b).then(f,m)}}function o(f,b){r[f]&&(a[f]=function(h){return new Promise(function(v,N){s.push([f,h,v,N])>1||l(f,h)})},b&&(a[f]=b(a[f])))}function l(f,b){try{u(r[f](b))}catch(h){p(s[0][3],h)}}function u(f){f.value instanceof pn?Promise.resolve(f.value.v).then(c,m):p(s[0][2],f)}function c(f){l("next",f)}function m(f){l("throw",f)}function p(f,b){f(b),s.shift(),s.length&&l(s[0][0],s[0][1])}};const fi={redirect:"error"};function Sm(e){var t;Im();const n=(t=e.useBinaryFormat)!==null&&t!==void 0?t:!1;return{async unary(r,a,s,i,o,l){const{serialize:u,parse:c}=ni(r,n,e.jsonOptions,e.binaryOptions);return s=s===void 0?e.defaultTimeoutMs:s<=0?void 0:s,await Nm({interceptors:e.interceptors,signal:a,timeoutMs:s,req:{stream:!1,service:r.parent,method:r,requestMethod:"POST",url:ti(e.baseUrl,r),header:li(r.methodKind,n,s,i,!1),contextValues:l??ei(),message:o},next:async m=>{var p;const f=e.useHttpGet===!0&&r.idempotency===qr.NO_SIDE_EFFECTS;let b=null;f?m=Em(m,u(m.message),n):b=u(m.message);const v=await((p=e.fetch)!==null&&p!==void 0?p:globalThis.fetch)(m.url,Object.assign(Object.assign({},fi),{method:m.requestMethod,headers:m.header,signal:m.signal,body:b})),{isUnaryError:N,unaryError:O}=ui(r.methodKind,n,v.status,v.headers);if(N)throw Il(await v.json(),Yd(...oi(v.headers)),O);const[T,_]=oi(v.headers);return{stream:!1,service:r.parent,method:r,header:T,message:n?c(new Uint8Array(await v.arrayBuffer())):cl(r.output,await v.json(),wl(e.jsonOptions)),trailer:_}}})},async stream(r,a,s,i,o,l){const{serialize:u,parse:c}=ni(r,n,e.jsonOptions,e.binaryOptions);function m(f,b,h,v){return xm(this,arguments,function*(){const O=Kd(f).getReader();let T=!1;for(;;){const _=yield pn(O.read());if(_.done)break;const{flags:w,data:A}=_.value;if((w&qs)===qs)throw new re("protocol error: received unsupported compressed output",J.Internal);if((w&si)===si){T=!0;const S=pm(A);if(S.error){const k=S.error;throw h.forEach((R,V)=>{k.metadata.append(V,R)}),k}S.metadata.forEach((k,R)=>b.set(R,k));continue}yield yield pn(c(A))}if("throwIfAborted"in v&&v.throwIfAborted(),!T)throw"missing EndStreamResponse"})}async function p(f){if(r.methodKind!="server_streaming")throw"The fetch API does not support streaming request bodies";const b=await f[Symbol.asyncIterator]().next();if(b.done==!0)throw"missing request message";return jd(0,u(b.value))}return s=s===void 0?e.defaultTimeoutMs:s<=0?void 0:s,await wm({interceptors:e.interceptors,timeoutMs:s,signal:a,req:{stream:!0,service:r.parent,method:r,requestMethod:"POST",url:ti(e.baseUrl,r),header:li(r.methodKind,n,s,i,!1),contextValues:l??ei(),message:o},next:async f=>{var b;const v=await((b=e.fetch)!==null&&b!==void 0?b:globalThis.fetch)(f.url,Object.assign(Object.assign({},fi),{method:f.requestMethod,headers:f.header,signal:f.signal,body:await p(f.message)}));if(ui(r.methodKind,n,v.status,v.headers),v.body===null)throw"missing response body";const N=new Headers;return Object.assign(Object.assign({},f),{header:v.headers,trailer:N,message:m(v.body,N,v.headers,f.signal)})}})}}}const Al=Sm({baseUrl:"/"}),Tm=vr("ChdoZWltZGFsbHIvdjEvYXV0aC5wcm90bxIMaGVpbWRhbGxyLnYxIjQKBFVzZXISCgoCaWQYASABKAkSEAoIdXNlcm5hbWUYAiABKAkSDgoGYXZhdGFyGAMgASgJIi8KBUd1aWxkEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEaWNvbhgDIAEoCSIUChJHZXRMb2dpblVSTFJlcXVlc3QiIgoTR2V0TG9naW5VUkxSZXNwb25zZRILCgN1cmwYASABKAkiIwoTRXhjaGFuZ2VDb2RlUmVxdWVzdBIMCgRjb2RlGAEgASgJIjgKFEV4Y2hhbmdlQ29kZVJlc3BvbnNlEiAKBHVzZXIYAiABKAsyEi5oZWltZGFsbHIudjEuVXNlciIXChVHZXRDdXJyZW50VXNlclJlcXVlc3QiOgoWR2V0Q3VycmVudFVzZXJSZXNwb25zZRIgCgR1c2VyGAEgASgLMhIuaGVpbWRhbGxyLnYxLlVzZXIiEwoRTGlzdEd1aWxkc1JlcXVlc3QiOQoSTGlzdEd1aWxkc1Jlc3BvbnNlEiMKBmd1aWxkcxgBIAMoCzITLmhlaW1kYWxsci52MS5HdWlsZCIPCg1Mb2dvdXRSZXF1ZXN0IhAKDkxvZ291dFJlc3BvbnNlMqsDCgtBdXRoU2VydmljZRJSCgtHZXRMb2dpblVSTBIgLmhlaW1kYWxsci52MS5HZXRMb2dpblVSTFJlcXVlc3QaIS5oZWltZGFsbHIudjEuR2V0TG9naW5VUkxSZXNwb25zZRJVCgxFeGNoYW5nZUNvZGUSIS5oZWltZGFsbHIudjEuRXhjaGFuZ2VDb2RlUmVxdWVzdBoiLmhlaW1kYWxsci52MS5FeGNoYW5nZUNvZGVSZXNwb25zZRJbCg5HZXRDdXJyZW50VXNlchIjLmhlaW1kYWxsci52MS5HZXRDdXJyZW50VXNlclJlcXVlc3QaJC5oZWltZGFsbHIudjEuR2V0Q3VycmVudFVzZXJSZXNwb25zZRJPCgpMaXN0R3VpbGRzEh8uaGVpbWRhbGxyLnYxLkxpc3RHdWlsZHNSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLkxpc3RHdWlsZHNSZXNwb25zZRJDCgZMb2dvdXQSGy5oZWltZGFsbHIudjEuTG9nb3V0UmVxdWVzdBocLmhlaW1kYWxsci52MS5Mb2dvdXRSZXNwb25zZUKuAQoQY29tLmhlaW1kYWxsci52MUIJQXV0aFByb3RvUAFaPmdpdGh1Yi5jb20vTkxMQ29tbXVuaXR5L2hlaW1kYWxsci9nZW4vaGVpbWRhbGxyL3YxO2hlaW1kYWxscnYxogIDSFhYqgIMSGVpbWRhbGxyLlYxygIMSGVpbWRhbGxyXFYx4gIYSGVpbWRhbGxyXFYxXEdQQk1ldGFkYXRh6gINSGVpbWRhbGxyOjpWMWIGcHJvdG8z"),Am=_l(Tm,0),ft=vr("CiFoZWltZGFsbHIvdjEvZ3VpbGRfc2V0dGluZ3MucHJvdG8SDGhlaW1kYWxsci52MSIoChRHZXRNb2RDaGFubmVsUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJNChdVcGRhdGVNb2RDaGFubmVsUmVxdWVzdBIyCghzZXR0aW5ncxgBIAEoCzIgLmhlaW1kYWxsci52MS5Nb2RDaGFubmVsU2V0dGluZ3MiQQoSTW9kQ2hhbm5lbFNldHRpbmdzEhAKCGd1aWxkX2lkGAEgASgJEhkKEW1vZGVyYXRvcl9jaGFubmVsGAIgASgJIjAKHEdldEluZnJhY3Rpb25TZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiVQofVXBkYXRlSW5mcmFjdGlvblNldHRpbmdzUmVxdWVzdBIyCghzZXR0aW5ncxgBIAEoCzIgLmhlaW1kYWxsci52MS5JbmZyYWN0aW9uU2V0dGluZ3MiigEKEkluZnJhY3Rpb25TZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIWCg5oYWxmX2xpZmVfZGF5cxgCIAEoARIiChpub3RpZnlfb25fd2FybmVkX3VzZXJfam9pbhgDIAEoCBImCh5ub3RpZnlfd2Fybl9zZXZlcml0eV90aHJlc2hvbGQYBCABKAEiLgoaR2V0R2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiUQodVXBkYXRlR2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QSMAoIc2V0dGluZ3MYASABKAsyHi5oZWltZGFsbHIudjEuR2F0ZWtlZXBTZXR0aW5ncyLdAQoQR2F0ZWtlZXBTZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIPCgdlbmFibGVkGAIgASgIEhQKDHBlbmRpbmdfcm9sZRgDIAEoCRIVCg1hcHByb3ZlZF9yb2xlGAQgASgJEiAKGGFkZF9wZW5kaW5nX3JvbGVfb25fam9pbhgFIAEoCBIYChBhcHByb3ZlZF9tZXNzYWdlGAYgASgJEhsKE2FwcHJvdmVkX21lc3NhZ2VfdjIYByABKAgSIAoYYXBwcm92ZWRfbWVzc2FnZV92Ml9qc29uGAggASgJIi8KG0dldEpvaW5MZWF2ZVNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJTCh5VcGRhdGVKb2luTGVhdmVTZXR0aW5nc1JlcXVlc3QSMQoIc2V0dGluZ3MYASABKAsyHy5oZWltZGFsbHIudjEuSm9pbkxlYXZlU2V0dGluZ3MikAIKEUpvaW5MZWF2ZVNldHRpbmdzEhAKCGd1aWxkX2lkGAEgASgJEhwKFGpvaW5fbWVzc2FnZV9lbmFibGVkGAIgASgIEhQKDGpvaW5fbWVzc2FnZRgDIAEoCRIdChVsZWF2ZV9tZXNzYWdlX2VuYWJsZWQYBCABKAgSFQoNbGVhdmVfbWVzc2FnZRgFIAEoCRIPCgdjaGFubmVsGAYgASgJEhcKD2pvaW5fbWVzc2FnZV92MhgHIAEoCBIcChRqb2luX21lc3NhZ2VfdjJfanNvbhgIIAEoCRIYChBsZWF2ZV9tZXNzYWdlX3YyGAkgASgIEh0KFWxlYXZlX21lc3NhZ2VfdjJfanNvbhgKIAEoCSIuChpHZXRBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJRCh1VcGRhdGVBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBIwCghzZXR0aW5ncxgBIAEoCzIeLmhlaW1kYWxsci52MS5BbnRpU3BhbVNldHRpbmdzIl4KEEFudGlTcGFtU2V0dGluZ3MSEAoIZ3VpbGRfaWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCBINCgVjb3VudBgDIAEoBRIYChBjb29sZG93bl9zZWNvbmRzGAQgASgFIi8KG0dldEJhbkZvb3RlclNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJTCh5VcGRhdGVCYW5Gb290ZXJTZXR0aW5nc1JlcXVlc3QSMQoIc2V0dGluZ3MYASABKAsyHy5oZWltZGFsbHIudjEuQmFuRm9vdGVyU2V0dGluZ3MiSgoRQmFuRm9vdGVyU2V0dGluZ3MSEAoIZ3VpbGRfaWQYASABKAkSDgoGZm9vdGVyGAIgASgJEhMKC2Fsd2F5c19zZW5kGAMgASgIIi0KGUdldE1vZG1haWxTZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiTwocVXBkYXRlTW9kbWFpbFNldHRpbmdzUmVxdWVzdBIvCghzZXR0aW5ncxgBIAEoCzIdLmhlaW1kYWxsci52MS5Nb2RtYWlsU2V0dGluZ3MiggEKD01vZG1haWxTZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIeChZyZXBvcnRfdGhyZWFkc19jaGFubmVsGAIgASgJEiMKG3JlcG9ydF9ub3RpZmljYXRpb25fY2hhbm5lbBgDIAEoCRIYChByZXBvcnRfcGluZ19yb2xlGAQgASgJIlYKB0NoYW5uZWwSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIMCgR0eXBlGAMgASgFEhAKCHBvc2l0aW9uGAQgASgFEhEKCXBhcmVudF9pZBgFIAEoCSJSCgRSb2xlEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDQoFY29sb3IYAyABKAUSEAoIcG9zaXRpb24YBCABKAUSDwoHbWFuYWdlZBgFIAEoCCInChNMaXN0Q2hhbm5lbHNSZXF1ZXN0EhAKCGd1aWxkX2lkGAEgASgJIj8KFExpc3RDaGFubmVsc1Jlc3BvbnNlEicKCGNoYW5uZWxzGAEgAygLMhUuaGVpbWRhbGxyLnYxLkNoYW5uZWwiJAoQTGlzdFJvbGVzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSI2ChFMaXN0Um9sZXNSZXNwb25zZRIhCgVyb2xlcxgBIAMoCzISLmhlaW1kYWxsci52MS5Sb2xlIl0KHFNlbmRDb21wb25lbnRzTWVzc2FnZVJlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkSEgoKY2hhbm5lbF9pZBgCIAEoCRIXCg9jb21wb25lbnRzX2pzb24YAyABKAkiMwodU2VuZENvbXBvbmVudHNNZXNzYWdlUmVzcG9uc2USEgoKbWVzc2FnZV9pZBgBIAEoCSI/ChNUZW1wbGF0ZVBsYWNlaG9sZGVyEhMKC3BsYWNlaG9sZGVyGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJIiAKHkdldFRlbXBsYXRlUGxhY2Vob2xkZXJzUmVxdWVzdCJaCh9HZXRUZW1wbGF0ZVBsYWNlaG9sZGVyc1Jlc3BvbnNlEjcKDHBsYWNlaG9sZGVycxgBIAMoCzIhLmhlaW1kYWxsci52MS5UZW1wbGF0ZVBsYWNlaG9sZGVyMpsOChRHdWlsZFNldHRpbmdzU2VydmljZRJVCg1HZXRNb2RDaGFubmVsEiIuaGVpbWRhbGxyLnYxLkdldE1vZENoYW5uZWxSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLk1vZENoYW5uZWxTZXR0aW5ncxJbChBVcGRhdGVNb2RDaGFubmVsEiUuaGVpbWRhbGxyLnYxLlVwZGF0ZU1vZENoYW5uZWxSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLk1vZENoYW5uZWxTZXR0aW5ncxJlChVHZXRJbmZyYWN0aW9uU2V0dGluZ3MSKi5oZWltZGFsbHIudjEuR2V0SW5mcmFjdGlvblNldHRpbmdzUmVxdWVzdBogLmhlaW1kYWxsci52MS5JbmZyYWN0aW9uU2V0dGluZ3MSawoYVXBkYXRlSW5mcmFjdGlvblNldHRpbmdzEi0uaGVpbWRhbGxyLnYxLlVwZGF0ZUluZnJhY3Rpb25TZXR0aW5nc1JlcXVlc3QaIC5oZWltZGFsbHIudjEuSW5mcmFjdGlvblNldHRpbmdzEl8KE0dldEdhdGVrZWVwU2V0dGluZ3MSKC5oZWltZGFsbHIudjEuR2V0R2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QaHi5oZWltZGFsbHIudjEuR2F0ZWtlZXBTZXR0aW5ncxJlChZVcGRhdGVHYXRla2VlcFNldHRpbmdzEisuaGVpbWRhbGxyLnYxLlVwZGF0ZUdhdGVrZWVwU2V0dGluZ3NSZXF1ZXN0Gh4uaGVpbWRhbGxyLnYxLkdhdGVrZWVwU2V0dGluZ3MSYgoUR2V0Sm9pbkxlYXZlU2V0dGluZ3MSKS5oZWltZGFsbHIudjEuR2V0Sm9pbkxlYXZlU2V0dGluZ3NSZXF1ZXN0Gh8uaGVpbWRhbGxyLnYxLkpvaW5MZWF2ZVNldHRpbmdzEmgKF1VwZGF0ZUpvaW5MZWF2ZVNldHRpbmdzEiwuaGVpbWRhbGxyLnYxLlVwZGF0ZUpvaW5MZWF2ZVNldHRpbmdzUmVxdWVzdBofLmhlaW1kYWxsci52MS5Kb2luTGVhdmVTZXR0aW5ncxJfChNHZXRBbnRpU3BhbVNldHRpbmdzEiguaGVpbWRhbGxyLnYxLkdldEFudGlTcGFtU2V0dGluZ3NSZXF1ZXN0Gh4uaGVpbWRhbGxyLnYxLkFudGlTcGFtU2V0dGluZ3MSZQoWVXBkYXRlQW50aVNwYW1TZXR0aW5ncxIrLmhlaW1kYWxsci52MS5VcGRhdGVBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBoeLmhlaW1kYWxsci52MS5BbnRpU3BhbVNldHRpbmdzEmIKFEdldEJhbkZvb3RlclNldHRpbmdzEikuaGVpbWRhbGxyLnYxLkdldEJhbkZvb3RlclNldHRpbmdzUmVxdWVzdBofLmhlaW1kYWxsci52MS5CYW5Gb290ZXJTZXR0aW5ncxJoChdVcGRhdGVCYW5Gb290ZXJTZXR0aW5ncxIsLmhlaW1kYWxsci52MS5VcGRhdGVCYW5Gb290ZXJTZXR0aW5nc1JlcXVlc3QaHy5oZWltZGFsbHIudjEuQmFuRm9vdGVyU2V0dGluZ3MSXAoSR2V0TW9kbWFpbFNldHRpbmdzEicuaGVpbWRhbGxyLnYxLkdldE1vZG1haWxTZXR0aW5nc1JlcXVlc3QaHS5oZWltZGFsbHIudjEuTW9kbWFpbFNldHRpbmdzEmIKFVVwZGF0ZU1vZG1haWxTZXR0aW5ncxIqLmhlaW1kYWxsci52MS5VcGRhdGVNb2RtYWlsU2V0dGluZ3NSZXF1ZXN0Gh0uaGVpbWRhbGxyLnYxLk1vZG1haWxTZXR0aW5ncxJVCgxMaXN0Q2hhbm5lbHMSIS5oZWltZGFsbHIudjEuTGlzdENoYW5uZWxzUmVxdWVzdBoiLmhlaW1kYWxsci52MS5MaXN0Q2hhbm5lbHNSZXNwb25zZRJMCglMaXN0Um9sZXMSHi5oZWltZGFsbHIudjEuTGlzdFJvbGVzUmVxdWVzdBofLmhlaW1kYWxsci52MS5MaXN0Um9sZXNSZXNwb25zZRJ2ChdHZXRUZW1wbGF0ZVBsYWNlaG9sZGVycxIsLmhlaW1kYWxsci52MS5HZXRUZW1wbGF0ZVBsYWNlaG9sZGVyc1JlcXVlc3QaLS5oZWltZGFsbHIudjEuR2V0VGVtcGxhdGVQbGFjZWhvbGRlcnNSZXNwb25zZRJwChVTZW5kQ29tcG9uZW50c01lc3NhZ2USKi5oZWltZGFsbHIudjEuU2VuZENvbXBvbmVudHNNZXNzYWdlUmVxdWVzdBorLmhlaW1kYWxsci52MS5TZW5kQ29tcG9uZW50c01lc3NhZ2VSZXNwb25zZUK3AQoQY29tLmhlaW1kYWxsci52MUISR3VpbGRTZXR0aW5nc1Byb3RvUAFaPmdpdGh1Yi5jb20vTkxMQ29tbXVuaXR5L2hlaW1kYWxsci9nZW4vaGVpbWRhbGxyL3YxO2hlaW1kYWxscnYxogIDSFhYqgIMSGVpbWRhbGxyLlYxygIMSGVpbWRhbGxyXFYx4gIYSGVpbWRhbGxyXFYxXEdQQk1ldGFkYXRh6gINSGVpbWRhbGxyOjpWMWIGcHJvdG8z"),qn=Le(ft,2),er=Le(ft,5),tr=Le(ft,8),nr=Le(ft,11),rr=Le(ft,14),ar=Le(ft,17),sr=Le(ft,20),km=_l(ft,0),ct=gl(Am,Al),ue=gl(km,Al);var Rm=x(''),Om=x('

Logging in...

'),Vm=x('
');function Gm(e,t){Y(t,!0);const n=()=>Ic(Lc,"$querystring",r),[r,a]=xc(),s=jt();let i=j(null);Kt(async()=>{const p=new URLSearchParams(n()??"").get("code");if(!p){F(i,"No authorization code received from Discord.");return}try{const f=await ct.exchangeCode({code:p});f.user&&(s.user=f.user),push("/guilds")}catch(f){F(i,f.message,!0)}});var o=Vm(),l=y(o);{var u=m=>{var p=Rm(),f=y(p),b=y(f),h=y(b);G(()=>D(h,d(i))),E(m,p)},c=m=>{var p=Om();E(m,p)};L(l,m=>{d(i)?m(u):m(c,!1)})}E(e,o),B(),a()}let di=j(ie([])),mi=j(!1);function _r(){return{get guilds(){return d(di)},set guilds(e){F(di,e,!0)},get loading(){return d(mi)},set loading(e){F(mi,e,!0)}}}var Lm=x(' Sandbox',1),Fm=x("
  • "),Um=x(''),Dm=x('
    '),Wm=x('
    '),Zm=x(''),Cm=x('');function Mm(e,t){Y(t,!0);const n=jt(),r=_r(),a=ae(()=>r.guilds.find(h=>h.id===t.currentGuildId));async function s(){try{await ct.logout({})}catch{}n.user=null,In("/")}var i=Cm(),o=y(i),l=I(y(o),2);{var u=h=>{var v=Lm(),N=q(v),O=y(N),T=I(N,2);G(()=>{D(O,`/ ${d(a).name??""}`),pe(T,"href",`/#/guild/${t.currentGuildId??""}/sandbox`)}),E(h,v)};L(l,h=>{d(a)&&h(u)})}var c=I(o,2),m=y(c);{var p=h=>{var v=Um(),N=I(y(v),2);ne(N,21,()=>r.guilds.filter(O=>O.id!==t.currentGuildId),te,(O,T)=>{var _=Fm(),w=y(_),A=y(w);G(()=>{pe(w,"href",`/#/guild/${d(T).id??""}`),D(A,d(T).name)}),E(O,_)}),E(h,v)};L(m,h=>{t.currentGuildId&&r.guilds.length>1&&h(p)})}var f=I(m,2);{var b=h=>{var v=Zm(),N=y(v),O=y(N);{var T=V=>{var U=Dm(),Z=y(U);G(()=>{pe(Z,"alt",n.user.username),pe(Z,"src",`https://cdn.discordapp.com/avatars/${n.user.id??""}/${n.user.avatar??""}.png?size=64`)}),E(V,U)},_=V=>{var U=Wm(),Z=y(U),le=y(Z);G($=>D(le,$),[()=>n.user.username.charAt(0).toUpperCase()]),E(V,U)};L(O,V=>{n.user.avatar?V(T):V(_,!1)})}var w=I(N,2),A=y(w),S=y(A),k=I(A,2),R=y(k);G(()=>D(S,n.user.username)),P("click",R,s),E(h,v)};L(f,h=>{n.user&&h(b)})}E(e,i),B()}ve(["click"]);let kl=j(ie([])),Rl=j(ie([])),na=j(!1),Ol="",qt=null,Vl=j(ie([])),Gl=!1,en=null;async function Ym(e){F(na,!0);try{const[t,n]=await Promise.all([ue.listChannels({guildId:e}),ue.listRoles({guildId:e})]);F(kl,t.channels,!0),F(Rl,n.roles,!0),Ol=e}finally{F(na,!1),qt=null}}async function Bm(){try{const e=await ue.getTemplatePlaceholders({});F(Vl,e.placeholders,!0),Gl=!0}finally{en=null}}function Er(){return{get channels(){return d(kl)},get roles(){return d(Rl)},get loading(){return d(na)},get placeholders(){return d(Vl)},load(e){return e===Ol?Promise.resolve():qt||(qt=Ym(e),qt)},loadPlaceholders(){return Gl?Promise.resolve():en||(en=Bm(),en)}}}var Pm=x(' '),Xm=x(''),Jm=x(""),Km=x(""),jm=x(""),zm=x(''),Hm=x('');function bn(e,t){Y(t,!0);const n=0,r=4,a=5;let i=Ie(t,"allowedTypes",3,[n,a]);const o=Er();wt(()=>{t.guildId&&o.load(t.guildId)});const l=ae(()=>{const T=o.channels,_=T.filter(S=>S.type===r);new Map(_.map(S=>[S.id,S]));const w=T.filter(S=>S.type!==r&&i().includes(S.type)),A=new Map;A.set("",{categoryName:"",categoryPosition:-1,channels:[]});for(const S of _)A.set(S.id,{categoryName:S.name,categoryPosition:S.position,channels:[]});for(const S of w){const k=S.parentId||"";let R=A.get(k);R||(R=A.get("")),R.channels.push({id:S.id,name:S.name,type:S.type,position:S.position})}for(const S of A.values())S.channels.sort((k,R)=>k.position-R.position);return[...A.values()].filter(S=>S.channels.length>0).sort((S,k)=>S.categoryPosition-k.categoryPosition)});function u(T){return T===a?"📢 ":"# "}var c=Hm(),m=y(c),p=y(m),f=y(p),b=I(p,2);{var h=T=>{var _=Pm(),w=y(_);G(()=>D(w,t.description)),E(T,_)};L(b,T=>{t.description&&T(h)})}var v=I(m,2);{var N=T=>{var _=Xm();E(T,_)},O=T=>{var _=zm(),w=y(_);w.value=w.__value="";var A=I(w);ne(A,17,()=>d(l),te,(k,R)=>{var V=Ce(),U=q(V);{var Z=$=>{var H=Km();ne(H,21,()=>d(R).channels,te,(_e,Fe)=>{var M=Jm(),Te=y(M),Ke={};G(Rt=>{D(Te,`${Rt??""}${d(Fe).name??""}`),Ke!==(Ke=d(Fe).id)&&(M.value=(M.__value=d(Fe).id)??"")},[()=>u(d(Fe).type)]),E(_e,M)}),G(()=>pe(H,"label",d(R).categoryName)),E($,H)},le=$=>{var H=Ce(),_e=q(H);ne(_e,17,()=>d(R).channels,te,(Fe,M)=>{var Te=jm(),Ke=y(Te),Rt={};G(Nr=>{D(Ke,`${Nr??""}${d(M).name??""}`),Rt!==(Rt=d(M).id)&&(Te.value=(Te.__value=d(M).id)??"")},[()=>u(d(M).type)]),E(Fe,Te)}),E($,H)};L(U,$=>{d(R).categoryName?$(Z):$(le,!1)})}E(k,V)});var S;dr(_),G(()=>{S!==(S=t.value)&&(_.value=(_.__value=t.value)??"",wn(_,t.value))}),P("change",_,k=>t.onchange(k.currentTarget.value)),E(T,_)};L(v,T=>{o.loading?T(N):T(O,!1)})}G(()=>D(f,t.label)),E(e,c),B()}ve(["change"]);var $m=x(' Saving...',1),Qm=x(' '),qm=x('
    ');function Tt(e,t){var n=qm(),r=y(n),a=y(r);{var s=u=>{var c=$m();E(u,c)},i=u=>{var c=ic("Save");E(u,c)};L(a,u=>{t.saving?u(s):u(i,!1)})}var o=I(r,2);{var l=u=>{var c=Qm(),m=y(c);G(()=>D(m,t.error)),E(u,c)};L(o,u=>{t.error&&u(l)})}G(()=>r.disabled=!t.dirty||t.saving),P("click",r,function(...u){t.onsave?.apply(this,u)}),E(e,n)}ve(["click"]);function At(e){return{data:Se(e),saved:Se(e),saving:!1,loading:!1,error:null}}async function mt(e,t,n){e.loading=!0,e.error=null;try{const r=await n();e.data=r,e.saved=Yo(t,r)}catch(r){e.error=r.message}finally{e.loading=!1}}async function pt(e,t,n){e.saving=!0,e.error=null;try{const r=await n();e.data=r,e.saved=Yo(t,r)}catch(r){e.error=r.message}finally{e.saving=!1}}let Gn=ie(At(qn)),Ln=ie(At(er)),Fn=ie(At(tr)),Un=ie(At(nr)),Dn=ie(At(rr)),Wn=ie(At(ar)),Zn=ie(At(sr));function dt(){return{get modChannel(){return Gn},get infractions(){return Ln},get gatekeep(){return Fn},get joinLeave(){return Un},get antiSpam(){return Dn},get banFooter(){return Wn},get modmail(){return Zn},async loadAll(e){await Promise.all([this.loadModChannel(e),this.loadInfractions(e),this.loadGatekeep(e),this.loadJoinLeave(e),this.loadAntiSpam(e),this.loadBanFooter(e),this.loadModmail(e)])},async loadModChannel(e){await mt(Gn,qn,()=>ue.getModChannel({guildId:e}))},async saveModChannel(){await pt(Gn,qn,()=>ue.updateModChannel({settings:Gn.data}))},async loadInfractions(e){await mt(Ln,er,()=>ue.getInfractionSettings({guildId:e}))},async saveInfractions(){await pt(Ln,er,()=>ue.updateInfractionSettings({settings:Ln.data}))},async loadGatekeep(e){await mt(Fn,tr,()=>ue.getGatekeepSettings({guildId:e}))},async saveGatekeep(){await pt(Fn,tr,()=>ue.updateGatekeepSettings({settings:Fn.data}))},async loadJoinLeave(e){await mt(Un,nr,()=>ue.getJoinLeaveSettings({guildId:e}))},async saveJoinLeave(){await pt(Un,nr,()=>ue.updateJoinLeaveSettings({settings:Un.data}))},async loadAntiSpam(e){await mt(Dn,rr,()=>ue.getAntiSpamSettings({guildId:e}))},async saveAntiSpam(){await pt(Dn,rr,()=>ue.updateAntiSpamSettings({settings:Dn.data}))},async loadBanFooter(e){await mt(Wn,ar,()=>ue.getBanFooterSettings({guildId:e}))},async saveBanFooter(){await pt(Wn,ar,()=>ue.updateBanFooterSettings({settings:Wn.data}))},async loadModmail(e){await mt(Zn,sr,()=>ue.getModmailSettings({guildId:e}))},async saveModmail(){await pt(Zn,sr,()=>ue.updateModmailSettings({settings:Zn.data}))}}}function kt(e,t,n){return!cd(e,t,n)}var ep=x(''),tp=x(" ",1),np=x('

    Moderator Channel

    The channel where bot notifications and moderator information are sent.

    ');function rp(e,t){Y(t,!0);const n=dt(),r=ae(()=>n.modChannel),a=ae(()=>kt(qn,d(r).data,d(r).saved));var s=np(),i=y(s),o=I(y(i),6);{var l=c=>{var m=ep();E(c,m)},u=c=>{var m=tp(),p=q(m);bn(p,{label:"Channel",description:"The Discord channel for moderator notifications",get value(){return d(r).data.moderatorChannel},get guildId(){return d(r).data.guildId},onchange:b=>d(r).data.moderatorChannel=b});var f=I(p,2);Tt(f,{get dirty(){return d(a)},get saving(){return d(r).saving},get error(){return d(r).error},onsave:()=>n.saveModChannel()}),E(c,m)};L(o,c=>{d(r).loading?c(l):c(u,!1)})}E(e,s),B()}var ap=x(' '),sp=x('');function ir(e,t){Y(t,!0);let n=Ie(t,"step",3,1);var r=sp(),a=y(r),s=y(a),i=y(s),o=I(s,2);{var l=c=>{var m=ap(),p=y(m);G(()=>D(p,t.description)),E(c,m)};L(o,c=>{t.description&&c(l)})}var u=I(a,2);G(()=>{D(i,t.label),fo(u,t.value),pe(u,"min",t.min),pe(u,"max",t.max),pe(u,"step",n())}),P("input",u,c=>t.onchange(Number(c.currentTarget.value))),E(e,r),B()}ve(["input"]);var ip=x(' '),op=x('');function xt(e,t){Y(t,!0);var n=op(),r=y(n),a=y(r),s=y(a),i=I(a,2);{var o=u=>{var c=ip(),m=y(c);G(()=>D(m,t.description)),E(u,c)};L(i,u=>{t.description&&u(o)})}var l=I(r,2);G(()=>{D(s,t.label),mo(l,t.checked)}),P("change",l,u=>t.onchange(u.currentTarget.checked)),E(e,n),B()}ve(["change"]);var lp=x(''),up=x(" ",1),cp=x('

    Infractions

    Configure infraction severity decay and join notifications for warned users.

    ');function fp(e,t){Y(t,!0);const n=dt(),r=ae(()=>n.infractions),a=ae(()=>kt(er,d(r).data,d(r).saved));var s=cp(),i=y(s),o=I(y(i),6);{var l=c=>{var m=lp();E(c,m)},u=c=>{var m=up(),p=q(m);ir(p,{label:"Half-life (days)",description:"How many days until an infraction's weight decays to half",get value(){return d(r).data.halfLifeDays},min:0,step:.5,onchange:v=>d(r).data.halfLifeDays=v});var f=I(p,2);xt(f,{label:"Notify on warned user join",description:"Post a notification when a user with warnings joins the server",get checked(){return d(r).data.notifyOnWarnedUserJoin},onchange:v=>d(r).data.notifyOnWarnedUserJoin=v});var b=I(f,2);ir(b,{label:"Notify severity threshold",description:"Minimum infraction severity to trigger a join notification",get value(){return d(r).data.notifyWarnSeverityThreshold},min:0,step:.1,onchange:v=>d(r).data.notifyWarnSeverityThreshold=v});var h=I(b,2);Tt(h,{get dirty(){return d(a)},get saving(){return d(r).saving},get error(){return d(r).error},onsave:()=>n.saveInfractions()}),E(c,m)};L(o,c=>{d(r).loading?c(l):c(u,!1)})}E(e,s),B()}var dp=x(' '),mp=x(''),pp=x(""),bp=x(''),vp=x('');function ra(e,t){Y(t,!0);const n=Er();wt(()=>{t.guildId&&n.load(t.guildId)});const r=ae(()=>n.roles.filter(f=>f.position>0&&!f.managed).sort((f,b)=>b.position-f.position));var a=vp(),s=y(a),i=y(s),o=y(i),l=I(i,2);{var u=f=>{var b=dp(),h=y(b);G(()=>D(h,t.description)),E(f,b)};L(l,f=>{t.description&&f(u)})}var c=I(s,2);{var m=f=>{var b=mp();E(f,b)},p=f=>{var b=bp(),h=y(b);h.value=h.__value="";var v=I(h);ne(v,17,()=>d(r),te,(O,T)=>{var _=pp(),w=y(_),A={};G(()=>{D(w,d(T).name),A!==(A=d(T).id)&&(_.value=(_.__value=d(T).id)??"")}),E(O,_)});var N;dr(b),G(()=>{N!==(N=t.value)&&(b.value=(b.__value=t.value)??"",wn(b,t.value))}),P("change",b,O=>t.onchange(O.currentTarget.value)),E(f,b)};L(c,f=>{n.loading?f(m):f(p,!1)})}G(()=>D(o,t.label)),E(e,a),B()}ve(["change"]);var gp=x(' '),hp=x('
     
    '),yp=x(' ',1),_p=x('
    ');function Ll(e,t){Y(t,!0);let n=j(!1);var r=_p(),a=y(r),s=y(a),i=y(s),o=I(s,2);{var l=p=>{var f=gp(),b=y(f);G(()=>D(b,t.description)),E(p,f)};L(o,p=>{t.description&&p(l)})}var u=I(a,2),c=I(u,2);{var m=p=>{var f=yp(),b=q(f),h=y(b),v=I(b,2);{var N=O=>{var T=hp(),_=y(T),w=y(_);G(()=>D(w,t.helpText)),E(O,T)};L(v,O=>{d(n)&&O(N)})}G(()=>D(h,`${d(n)?"Hide":"Show"} template placeholders`)),P("click",b,()=>F(n,!d(n))),E(p,f)};L(c,p=>{t.helpText&&p(m)})}G(()=>{D(i,t.label),pe(u,"placeholder",t.placeholder),fo(u,t.value)}),P("input",u,p=>t.onchange(p.currentTarget.value)),E(e,r),B()}ve(["input","click"]);const se={action_row:1,button:2,section:9,text_display:10,thumbnail:11,media_gallery:12,separator:14,container:17},Ep={primary:1,secondary:2,success:3,danger:4,link:5};function pi(e){const t={type:se.button,style:Ep[e.style],label:e.label};if(e.style==="link"&&e.url?t.url=e.url:e.customId&&(t.custom_id=e.customId),e.emoji){const n=e.emoji.match(/^<(a?):(\w+):(\d+)>$/);n?t.emoji={name:n[2],id:n[3]}:t.emoji={name:e.emoji}}return t}function Np(e){if(!e||e==="#000000"||e==="")return;const t=e.replace("#",""),n=parseInt(t,16);return isNaN(n)?void 0:n}function Fl(e){switch(e.type){case"text_display":return{type:se.text_display,content:e.content};case"section":{const t=e.texts.filter(r=>r.trim()).map(r=>({type:se.text_display,content:r}));if(t.length===0)return null;const n={type:se.section,components:t};return e.accessory&&(e.accessory.kind==="thumbnail"?n.accessory={type:se.thumbnail,media:{url:e.accessory.url}}:e.accessory.kind==="button"&&(n.accessory=pi({label:e.accessory.label,style:e.accessory.style,customId:e.accessory.customId,url:e.accessory.url,emoji:e.accessory.emoji}))),n}case"container":{const t=e.children.map(Fl).filter(a=>a!==null);if(t.length===0)return null;const n={type:se.container,components:t},r=Np(e.accentColor);return r!==void 0&&(n.accent_color=r),e.spoiler&&(n.spoiler=!0),n}case"separator":return{type:se.separator,spacing:e.spacing==="large"?2:1,divider:e.divider};case"media_gallery":{const t=e.items.filter(n=>n.url.trim()).map(n=>{const r={media:{url:n.url}};return n.description&&(r.description=n.description),r});return t.length===0?null:{type:se.media_gallery,items:t}}case"action_row":{const t=e.buttons.filter(n=>n.label.trim()).map(pi);return t.length===0?null:{type:se.action_row,components:t}}default:return null}}const wp={1:"primary",2:"secondary",3:"success",4:"danger",5:"link"};function Ip(e){return e===void 0||e===0?"":"#"+e.toString(16).padStart(6,"0")}function bi(e){const t=wp[e.style??1]??"primary",n={label:e.label??"",style:t};if(e.custom_id&&(n.customId=e.custom_id),e.url&&(n.url=e.url),e.emoji){const r=e.emoji;r.id?n.emoji=`<:${r.name}:${r.id}>`:r.name&&(n.emoji=r.name)}return n}function Ul(e){switch(e.type){case se.text_display:return{type:"text_display",content:e.content??""};case se.section:{const r=(e.components??[]).filter(s=>s.type===se.text_display).map(s=>s.content??"");r.length===0&&r.push("");const a={type:"section",texts:r};if(e.accessory){const s=e.accessory;if(s.type===se.thumbnail){const i=s.media;a.accessory={kind:"thumbnail",url:i?.url??""}}else if(s.type===se.button){const i=bi(s);a.accessory={kind:"button",label:i.label,style:i.style,customId:i.customId??"",url:i.url,emoji:i.emoji}}}return a}case se.container:{const n=(e.components??[]).map(Ul).filter(r=>r!==null);return{type:"container",accentColor:Ip(e.accent_color),spoiler:e.spoiler??!1,children:n}}case se.separator:return{type:"separator",spacing:e.spacing===2?"large":"small",divider:e.divider??!0};case se.media_gallery:{const n=(e.items??[]).map(r=>({url:r.media?.url??"",description:r.description}));return n.length===0&&n.push({url:""}),{type:"media_gallery",items:n}}case se.action_row:{const r=(e.components??[]).filter(a=>a.type===se.button).map(bi);return r.length===0?null:{type:"action_row",buttons:r}}default:return null}}function xp(e){if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t.map(Ul).filter(n=>n!==null):[]}catch{return[]}}function Dl(e){const t=e.map(Fl).filter(n=>n!==null);return JSON.stringify(t)}function Wl(e){switch(e){case"text_display":return{type:"text_display",content:""};case"section":return{type:"section",texts:[""],accessory:void 0};case"container":return{type:"container",accentColor:"",spoiler:!1,children:[]};case"separator":return{type:"separator",spacing:"small",divider:!0};case"media_gallery":return{type:"media_gallery",items:[{url:""}]};case"action_row":return{type:"action_row",buttons:[{label:"Button",style:"primary",customId:"btn_1"}]}}}var Sp=x('
    Markdown Content
    ');function Tp(e,t){Y(t,!0);let n=Ie(t,"node",7);var r=Sp(),a=I(y(r),2);Ne(a,()=>n().content,s=>n().content=s),E(e,r),B()}var Ap=x(''),kp=x('
    '),Rp=x(''),Op=x(''),Vp=x('
    ',1),Gp=x('
    Text Fields
    Accessory
    ');function Lp(e,t){Y(t,!0);let n=Ie(t,"node",7),r=ae(()=>n().accessory?.kind??"none");function a(w){w==="none"?n().accessory=void 0:w==="thumbnail"?n().accessory={kind:"thumbnail",url:""}:n().accessory={kind:"button",label:"Click",style:"link",customId:"",url:""}}function s(){n().texts=[...n().texts,""]}function i(w){n().texts=n().texts.filter((A,S)=>S!==w)}var o=Gp(),l=y(o),u=I(y(l),2);ne(u,17,()=>n().texts,te,(w,A,S)=>{var k=kp(),R=y(k),V=I(R,2);{var U=Z=>{var le=Ap();P("click",le,()=>i(S)),E(Z,le)};L(V,Z=>{n().texts.length>1&&Z(U)})}Ne(R,()=>n().texts[S],Z=>n().texts[S]=Z),E(w,k)});var c=I(u,2);{var m=w=>{var A=Rp();P("click",A,s),E(w,A)};L(c,w=>{n().texts.length<3&&w(m)})}var p=I(l,2),f=I(y(p),2),b=y(f);b.value=b.__value="none";var h=I(b);h.value=h.__value="thumbnail";var v=I(h);v.value=v.__value="button";var N;dr(f);var O=I(f,2);{var T=w=>{var A=Op();Ne(A,()=>n().accessory.url,S=>n().accessory.url=S),E(w,A)},_=w=>{var A=Vp(),S=q(A),k=y(S),R=I(k,2),V=I(S,2);Ne(k,()=>n().accessory.label,U=>n().accessory.label=U),Ne(R,()=>n().accessory.emoji,U=>n().accessory.emoji=U),Ne(V,()=>n().accessory.url,U=>n().accessory.url=U),E(w,A)};L(O,w=>{n().accessory?.kind==="thumbnail"?w(T):n().accessory?.kind==="button"&&w(_,1)})}G(()=>{N!==(N=d(r))&&(f.value=(f.__value=d(r))??"",wn(f,d(r)))}),P("change",f,w=>a(w.currentTarget.value)),E(e,o),B()}ve(["click","change"]);var Fp=x('
    '),Up=x("
  • "),Dp=x('
    Children
    ');function Wp(e,t){Y(t,!0);let n=Ie(t,"node",7);const r=[{value:"text_display",label:"Text Display"},{value:"section",label:"Section"},{value:"separator",label:"Separator"},{value:"media_gallery",label:"Media Gallery"},{value:"action_row",label:"Action Row"}];function a(){document.activeElement?.blur()}function s(O){n().children=[...n().children,Wl(O)],a()}function i(O){n().children=n().children.filter((T,_)=>_!==O)}function o(O,T){const _=O+T;if(_<0||_>=n().children.length)return;const w=[...n().children];[w[O],w[_]]=[w[_],w[O]],n().children=w}var l=Dp(),u=y(l),c=y(u),m=I(y(c),2),p=I(c,2),f=y(p),b=I(u,2),h=I(y(b),2);ne(h,17,()=>n().children,te,(O,T,_)=>{var w=Fp(),A=y(w),S=y(A),k=y(S),R=I(S,2),V=y(R);V.disabled=_===0;var U=I(V,2),Z=I(U,2),le=I(A,2);Zl(le,{get node(){return d(T)}}),G($=>{D(k,$),U.disabled=_===n().children.length-1},[()=>d(T).type.replace("_"," ")]),P("click",V,()=>o(_,-1)),P("click",U,()=>o(_,1)),P("click",Z,()=>i(_)),E(O,w)});var v=I(h,2),N=I(y(v),2);ne(N,21,()=>r,te,(O,T)=>{var _=Up(),w=y(_),A=y(w);G(()=>D(A,d(T).label)),P("click",w,()=>s(d(T).value)),E(O,_)}),Ne(m,()=>n().accentColor,O=>n().accentColor=O),po(f,()=>n().spoiler,O=>n().spoiler=O),E(e,l),B()}ve(["click"]);var Zp=x('
    ');function Cp(e,t){Y(t,!0);let n=Ie(t,"node",7);var r=Zp(),a=y(r),s=I(y(a),2),i=y(s);i.value=i.__value="small";var o=I(i);o.value=o.__value="large";var l=I(a,2),u=y(l);co(s,()=>n().spacing,c=>n().spacing=c),po(u,()=>n().divider,c=>n().divider=c),E(e,r),B()}var Mp=x(''),Yp=x('
    '),Bp=x(''),Pp=x('
    Media Items
    ');function Xp(e,t){Y(t,!0);let n=Ie(t,"node",7);function r(){n().items=[...n().items,{url:""}]}function a(u){n().items=n().items.filter((c,m)=>m!==u)}var s=Pp(),i=I(y(s),2);ne(i,17,()=>n().items,te,(u,c,m)=>{var p=Yp(),f=y(p),b=I(f,2),h=I(b,2);{var v=N=>{var O=Mp();P("click",O,()=>a(m)),E(N,O)};L(h,N=>{n().items.length>1&&N(v)})}Ne(f,()=>d(c).url,N=>d(c).url=N),Ne(b,()=>d(c).description,N=>d(c).description=N),E(u,p)});var o=I(i,2);{var l=u=>{var c=Bp();P("click",c,r),E(u,c)};L(o,u=>{n().items.length<10&&u(l)})}E(e,s),B()}ve(["click"]);var Jp=x(""),Kp=x(''),jp=x(''),zp=x(''),Hp=x('
    '),$p=x(''),Qp=x('
    Buttons
    ');function qp(e,t){Y(t,!0);let n=Ie(t,"node",7);const r=[{value:"primary",label:"Primary"},{value:"secondary",label:"Secondary"},{value:"success",label:"Success"},{value:"danger",label:"Danger"},{value:"link",label:"Link"}];function a(){n().buttons=[...n().buttons,{label:"Button",style:"secondary",customId:`btn_${Date.now()}`}]}function s(c){n().buttons=n().buttons.filter((m,p)=>p!==c)}var i=Qp(),o=I(y(i),2);ne(o,17,()=>n().buttons,te,(c,m,p)=>{var f=Hp(),b=y(f),h=y(b),v=I(h,2);ne(v,21,()=>r,te,(k,R)=>{var V=Jp(),U=y(V),Z={};G(()=>{D(U,d(R).label),Z!==(Z=d(R).value)&&(V.value=(V.__value=d(R).value)??"")}),E(k,V)});var N=I(v,2);{var O=k=>{var R=Kp();P("click",R,()=>s(p)),E(k,R)};L(N,k=>{n().buttons.length>1&&k(O)})}var T=I(b,2),_=y(T);{var w=k=>{var R=jp();Ne(R,()=>d(m).url,V=>d(m).url=V),E(k,R)},A=k=>{var R=zp();Ne(R,()=>d(m).customId,V=>d(m).customId=V),E(k,R)};L(_,k=>{d(m).style==="link"?k(w):k(A,!1)})}var S=I(_,2);Ne(h,()=>d(m).label,k=>d(m).label=k),co(v,()=>d(m).style,k=>d(m).style=k),Ne(S,()=>d(m).emoji,k=>d(m).emoji=k),E(c,f)});var l=I(o,2);{var u=c=>{var m=$p();P("click",m,a),E(c,m)};L(l,c=>{n().buttons.length<5&&c(u)})}E(e,i),B()}ve(["click"]);function Zl(e,t){Y(t,!0);var n=Ce(),r=q(n);{var a=c=>{Tp(c,{get node(){return t.node}})},s=c=>{Lp(c,{get node(){return t.node}})},i=c=>{Wp(c,{get node(){return t.node}})},o=c=>{Cp(c,{get node(){return t.node}})},l=c=>{Xp(c,{get node(){return t.node}})},u=c=>{qp(c,{get node(){return t.node}})};L(r,c=>{t.node.type==="text_display"?c(a):t.node.type==="section"?c(s,1):t.node.type==="container"?c(i,2):t.node.type==="separator"?c(o,3):t.node.type==="media_gallery"?c(l,4):t.node.type==="action_row"&&c(u,5)})}E(e,n),B()}var eb=x('
    '),tb=x('
    No components yet. Add one below to get started.
    '),nb=x("
  • "),rb=x('
    ');function Cl(e,t){Y(t,!0);let n=Ie(t,"components",15);const r=[{value:"text_display",label:"Text Display"},{value:"section",label:"Section"},{value:"container",label:"Container"},{value:"separator",label:"Separator"},{value:"media_gallery",label:"Media Gallery"},{value:"action_row",label:"Action Row"}];function a(){document.activeElement?.blur()}function s(b){n([...n(),Wl(b)]),a()}function i(b){n(n().filter((h,v)=>v!==b))}function o(b,h){const v=b+h;if(v<0||v>=n().length)return;const N=[...n()];[N[b],N[v]]=[N[v],N[b]],n(N)}var l=rb(),u=y(l);ne(u,17,n,te,(b,h,v)=>{var N=eb(),O=y(N),T=y(O),_=y(T),w=y(_),A=I(_,2),S=y(A);S.disabled=v===0;var k=I(S,2),R=I(k,2),V=I(T,2);Zl(V,{get node(){return d(h)}}),G(U=>{D(w,U),k.disabled=v===n().length-1},[()=>d(h).type.replace("_"," ")]),P("click",S,()=>o(v,-1)),P("click",k,()=>o(v,1)),P("click",R,()=>i(v)),E(b,N)});var c=I(u,2);{var m=b=>{var h=tb();E(b,h)};L(c,b=>{n().length===0&&b(m)})}var p=I(c,2),f=I(y(p),2);ne(f,21,()=>r,te,(b,h)=>{var v=nb(),N=y(v),O=y(N);G(()=>D(O,d(h).label)),P("click",N,()=>s(d(h).value)),E(b,v)}),E(e,l),B()}ve(["click"]);var ab=x('
    '),sb=x('
    '),ib=x('Thumbnail'),ob=x(' '),lb=x(''),ub=x('
    '),cb=x('
    '),fb=x("
    "),db=x("
    "),mb=x('
    '),pb=x('
    '),bb=x(' '),vb=x(''),gb=x('
    '),hb=x('
    Nothing to preview
    '),yb=x('
    '),_b=x('

    Preview

    ');function Ml(e,t){Y(t,!0);const n=(u,c=Ye)=>{var m=Ce(),p=q(m);{var f=T=>{var _=ab(),w=y(_);G(()=>D(w,c().content||" ")),E(T,_)},b=T=>{var _=ub(),w=y(_);ne(w,21,()=>c().texts.filter(R=>R.trim()),te,(R,V)=>{var U=sb(),Z=y(U);G(()=>D(Z,d(V))),E(R,U)});var A=I(w,2);{var S=R=>{var V=ib();G(()=>pe(V,"src",c().accessory.url)),$a("error",V,U=>{U.currentTarget.style.display="none"}),E(R,V)},k=R=>{var V=lb(),U=y(V);{var Z=$=>{var H=ob(),_e=y(H);G(()=>D(_e,c().accessory.emoji)),E($,H)};L(U,$=>{c().accessory.emoji&&$(Z)})}var le=I(U);G($=>{Gt(V,1,`btn btn-sm ${$??""}`),D(le,` ${c().accessory.label??""}`)},[()=>r(c().accessory.style)]),E(R,V)};L(A,R=>{c().accessory?.kind==="thumbnail"&&c().accessory.url?R(S):c().accessory?.kind==="button"&&R(k,1)})}E(T,_)},h=T=>{var _=cb();let w,A;var S=y(_);ne(S,21,()=>c().children,te,(k,R)=>{n(k,()=>d(R))}),G(()=>{w=Gt(_,1,"rounded-lg border-l-4 p-3",null,w,{"blur-sm":c().spoiler}),A=gc(_,"",A,{"border-color":c().accentColor||"oklch(var(--bc) / 0.2)"})}),E(T,_)},v=T=>{var _=Ce(),w=q(_);{var A=k=>{var R=fb();G(()=>Gt(R,1,es(c().spacing==="large"?"my-3":"my-1"))),E(k,R)},S=k=>{var R=db();G(()=>Gt(R,1,es(c().spacing==="large"?"h-6":"h-2"))),E(k,R)};L(w,k=>{c().divider?k(A):k(S,!1)})}E(T,_)},N=T=>{var _=pb();ne(_,21,()=>c().items.filter(w=>w.url.trim()),te,(w,A)=>{var S=mb(),k=y(S);G(()=>{pe(k,"src",d(A).url),pe(k,"alt",d(A).description||"Media")}),$a("error",k,R=>{const V=R.currentTarget;V.style.display="none",V.nextElementSibling?.classList.remove("hidden")}),E(w,S)}),E(T,_)},O=T=>{var _=gb();ne(_,21,()=>c().buttons.filter(w=>w.label.trim()),te,(w,A)=>{var S=vb(),k=y(S);{var R=U=>{var Z=bb(),le=y(Z);G(()=>D(le,d(A).emoji)),E(U,Z)};L(k,U=>{d(A).emoji&&U(R)})}var V=I(k);G(U=>{Gt(S,1,`btn btn-sm ${U??""}`),D(V,` ${d(A).label??""}`)},[()=>r(d(A).style)]),E(w,S)}),E(T,_)};L(p,T=>{c().type==="text_display"?T(f):c().type==="section"?T(b,1):c().type==="container"?T(h,2):c().type==="separator"?T(v,3):c().type==="media_gallery"?T(N,4):c().type==="action_row"&&T(O,5)})}E(u,m)};function r(u){switch(u){case"primary":return"btn-primary";case"secondary":return"btn-neutral";case"success":return"btn-success";case"danger":return"btn-error";case"link":return"btn-link"}}var a=_b(),s=y(a),i=I(y(s),2);{var o=u=>{var c=hb();E(u,c)},l=u=>{var c=yb();ne(c,21,()=>t.components,te,(m,p)=>{n(m,()=>d(p))}),E(u,c)};L(i,u=>{t.components.length===0?u(o):u(l,!1)})}E(e,a),B()}var Eb=x(' '),Nb=x('
    '),wb=x('
    ',1);function aa(e,t){Y(t,!0);let n=j(void 0),r=j(ie([]));function a(){try{const M=JSON.parse(t.v2Json||"[]");return Array.isArray(M)?M.length:0}catch{return 0}}function s(){F(r,xp(t.v2Json),!0),d(n)?.showModal()}function i(){t.onV2JsonChange(Dl(d(r))),d(n)?.close()}var o=wb(),l=q(o),u=y(l),c=y(u),m=y(c),p=I(c,2);{var f=M=>{var Te=Eb(),Ke=y(Te);G(()=>D(Ke,t.description)),E(M,Te)};L(p,M=>{t.description&&M(f)})}var b=I(u,2),h=y(b),v=I(b,2);{var N=M=>{var Te=Nb(),Ke=y(Te),Rt=y(Ke),Nr=I(Ke,2);G((Bl,Pl)=>D(Rt,`${Bl??""} component${Pl??""} configured`),[a,()=>a()!==1?"s":""]),P("click",Nr,s),E(M,Te)},O=M=>{Ll(M,{label:"",get value(){return t.plainText},get helpText(){return t.helpText},get onchange(){return t.onPlainTextChange}})};L(v,M=>{t.v2Enabled?M(N):M(O,!1)})}var T=I(l,2),_=y(T),w=y(_),A=y(w),S=y(A),k=I(A,2),R=I(w,2),V=y(R),U=y(V);Cl(U,{get components(){return d(r)},set components(M){F(r,M,!0)}});var Z=I(V,2),le=y(Z);Ml(le,{get components(){return d(r)}});var $=I(R,2),H=y($),_e=I(_,2),Fe=y(_e);Nc(T,M=>F(n,M),()=>d(n)),G(()=>{D(m,t.label),mo(h,t.v2Enabled),D(S,`${t.label??""} - Components V2 Editor`)}),P("change",h,M=>t.onV2EnabledChange(M.currentTarget.checked)),P("click",k,i),P("click",H,i),P("click",Fe,i),E(e,o),B()}ve(["change","click"]);var Ib=x(''),xb=x(" ",1),Sb=x('

    Gatekeep

    Member verification system. New members get a pending role and must be approved to access the server.

    ');function Tb(e,t){Y(t,!0);const n=dt(),r=Er(),a=ae(()=>n.gatekeep),s=ae(()=>kt(tr,d(a).data,d(a).saved));wt(()=>{r.loadPlaceholders()});const i=ae(()=>r.placeholders.map(p=>`${p.placeholder} — ${p.description}`).join(` +`));var o=Sb(),l=y(o),u=I(y(l),6);{var c=p=>{var f=Ib();E(p,f)},m=p=>{var f=xb(),b=q(f);xt(b,{label:"Enabled",description:"Enable the gatekeep verification system",get checked(){return d(a).data.enabled},onchange:_=>d(a).data.enabled=_});var h=I(b,2);ra(h,{label:"Pending Role",description:"Role assigned to unverified members",get value(){return d(a).data.pendingRole},get guildId(){return d(a).data.guildId},onchange:_=>d(a).data.pendingRole=_});var v=I(h,2);ra(v,{label:"Approved Role",description:"Role assigned to verified members",get value(){return d(a).data.approvedRole},get guildId(){return d(a).data.guildId},onchange:_=>d(a).data.approvedRole=_});var N=I(v,2);xt(N,{label:"Add pending role on join",description:"Automatically assign the pending role when a new member joins",get checked(){return d(a).data.addPendingRoleOnJoin},onchange:_=>d(a).data.addPendingRoleOnJoin=_});var O=I(N,2);aa(O,{label:"Approved message",description:"Message sent to the user when they are approved",get helpText(){return d(i)},get plainText(){return d(a).data.approvedMessage},get v2Enabled(){return d(a).data.approvedMessageV2},get v2Json(){return d(a).data.approvedMessageV2Json},onPlainTextChange:_=>d(a).data.approvedMessage=_,onV2EnabledChange:_=>d(a).data.approvedMessageV2=_,onV2JsonChange:_=>d(a).data.approvedMessageV2Json=_});var T=I(O,2);Tt(T,{get dirty(){return d(s)},get saving(){return d(a).saving},get error(){return d(a).error},onsave:()=>n.saveGatekeep()}),E(p,f)};L(u,p=>{d(a).loading?p(c):p(m,!1)})}E(e,o),B()}var Ab=x(''),kb=x('
    Join Message
    Leave Message
    ',1),Rb=x('

    Join/Leave Messages

    Configure messages sent when members join or leave the server.

    ');function Ob(e,t){Y(t,!0);const n=dt(),r=Er(),a=ae(()=>n.joinLeave),s=ae(()=>kt(nr,d(a).data,d(a).saved));wt(()=>{r.loadPlaceholders()});const i=ae(()=>r.placeholders.map(p=>`${p.placeholder} — ${p.description}`).join(` +`));var o=Rb(),l=y(o),u=I(y(l),6);{var c=p=>{var f=Ab();E(p,f)},m=p=>{var f=kb(),b=q(f);bn(b,{label:"Channel",description:"Channel where join/leave messages are sent",get value(){return d(a).data.channel},get guildId(){return d(a).data.guildId},onchange:_=>d(a).data.channel=_});var h=I(b,4);xt(h,{label:"Join message enabled",get checked(){return d(a).data.joinMessageEnabled},onchange:_=>d(a).data.joinMessageEnabled=_});var v=I(h,2);aa(v,{label:"Join message",get helpText(){return d(i)},get plainText(){return d(a).data.joinMessage},get v2Enabled(){return d(a).data.joinMessageV2},get v2Json(){return d(a).data.joinMessageV2Json},onPlainTextChange:_=>d(a).data.joinMessage=_,onV2EnabledChange:_=>d(a).data.joinMessageV2=_,onV2JsonChange:_=>d(a).data.joinMessageV2Json=_});var N=I(v,4);xt(N,{label:"Leave message enabled",get checked(){return d(a).data.leaveMessageEnabled},onchange:_=>d(a).data.leaveMessageEnabled=_});var O=I(N,2);aa(O,{label:"Leave message",get helpText(){return d(i)},get plainText(){return d(a).data.leaveMessage},get v2Enabled(){return d(a).data.leaveMessageV2},get v2Json(){return d(a).data.leaveMessageV2Json},onPlainTextChange:_=>d(a).data.leaveMessage=_,onV2EnabledChange:_=>d(a).data.leaveMessageV2=_,onV2JsonChange:_=>d(a).data.leaveMessageV2Json=_});var T=I(O,2);Tt(T,{get dirty(){return d(s)},get saving(){return d(a).saving},get error(){return d(a).error},onsave:()=>n.saveJoinLeave()}),E(p,f)};L(u,p=>{d(a).loading?p(c):p(m,!1)})}E(e,o),B()}var Vb=x(''),Gb=x(" ",1),Lb=x('

    Anti-Spam

    Automatically detect and act on spam messages.

    ');function Fb(e,t){Y(t,!0);const n=dt(),r=ae(()=>n.antiSpam),a=ae(()=>kt(rr,d(r).data,d(r).saved));var s=Lb(),i=y(s),o=I(y(i),6);{var l=c=>{var m=Vb();E(c,m)},u=c=>{var m=Gb(),p=q(m);xt(p,{label:"Enabled",description:"Enable anti-spam detection",get checked(){return d(r).data.enabled},onchange:v=>d(r).data.enabled=v});var f=I(p,2);ir(f,{label:"Message count",description:"Number of messages within the cooldown period to trigger anti-spam",get value(){return d(r).data.count},min:2,max:10,onchange:v=>d(r).data.count=v});var b=I(f,2);ir(b,{label:"Cooldown (seconds)",description:"Time window in seconds for counting messages",get value(){return d(r).data.cooldownSeconds},min:1,max:60,onchange:v=>d(r).data.cooldownSeconds=v});var h=I(b,2);Tt(h,{get dirty(){return d(a)},get saving(){return d(r).saving},get error(){return d(r).error},onsave:()=>n.saveAntiSpam()}),E(c,m)};L(o,c=>{d(r).loading?c(l):c(u,!1)})}E(e,s),B()}var Ub=x(''),Db=x(" ",1),Wb=x('');function Zb(e,t){Y(t,!0);const n=dt(),r=ae(()=>n.banFooter),a=ae(()=>kt(ar,d(r).data,d(r).saved));var s=Wb(),i=y(s),o=I(y(i),6);{var l=c=>{var m=Ub();E(c,m)},u=c=>{var m=Db(),p=q(m);Ll(p,{label:"Footer text",description:"Text appended to ban DM messages (e.g., appeal information)",get value(){return d(r).data.footer},onchange:h=>d(r).data.footer=h});var f=I(p,2);xt(f,{label:"Always send footer",description:"Send the footer even when no custom reason is provided",get checked(){return d(r).data.alwaysSend},onchange:h=>d(r).data.alwaysSend=h});var b=I(f,2);Tt(b,{get dirty(){return d(a)},get saving(){return d(r).saving},get error(){return d(r).error},onsave:()=>n.saveBanFooter()}),E(c,m)};L(o,c=>{d(r).loading?c(l):c(u,!1)})}E(e,s),B()}var Cb=x(''),Mb=x(" ",1),Yb=x('

    Modmail

    Configure channels and roles for the modmail report system.

    ');function Bb(e,t){Y(t,!0);const n=dt(),r=ae(()=>n.modmail),a=ae(()=>kt(sr,d(r).data,d(r).saved));var s=Yb(),i=y(s),o=I(y(i),6);{var l=c=>{var m=Cb();E(c,m)},u=c=>{var m=Mb(),p=q(m);bn(p,{label:"Report threads channel",description:"Channel where report threads are created",get value(){return d(r).data.reportThreadsChannel},get guildId(){return d(r).data.guildId},onchange:v=>d(r).data.reportThreadsChannel=v});var f=I(p,2);bn(f,{label:"Report notification channel",description:"Channel where new report notifications are posted",get value(){return d(r).data.reportNotificationChannel},get guildId(){return d(r).data.guildId},onchange:v=>d(r).data.reportNotificationChannel=v});var b=I(f,2);ra(b,{label:"Report ping role",description:"Role pinged when a new report is submitted",get value(){return d(r).data.reportPingRole},get guildId(){return d(r).data.guildId},onchange:v=>d(r).data.reportPingRole=v});var h=I(b,2);Tt(h,{get dirty(){return d(a)},get saving(){return d(r).saving},get error(){return d(r).error},onsave:()=>n.saveModmail()}),E(c,m)};L(o,c=>{d(r).loading?c(l):c(u,!1)})}E(e,s),B()}const Yl=[{id:"mod-channel",label:"Moderator Channel",component:rp},{id:"infractions",label:"Infractions",component:fp},{id:"gatekeep",label:"Gatekeep",component:Tb},{id:"join-leave",label:"Join/Leave Messages",component:Ob},{id:"anti-spam",label:"Anti-Spam",component:Fb},{id:"ban-footer",label:"Ban Footer",component:Zb},{id:"modmail",label:"Modmail",component:Bb}];var Pb=x('
  • '),Xb=x('');function Jb(e,t){Y(t,!1);function n(i){document.getElementById(i)?.scrollIntoView({behavior:"smooth"})}ga();var r=Xb(),a=y(r),s=I(y(a),2);ne(s,1,()=>Yl,te,(i,o)=>{var l=Pb(),u=y(l),c=y(u);G(()=>D(c,d(o).label)),P("click",u,()=>n(d(o).id)),E(i,l)}),E(e,r),B()}ve(["click"]);var Kb=x('
    ');function Ya(e,t){let n=Ie(t,"showSidebar",3,!1);var r=Kb(),a=y(r);Mm(a,{get currentGuildId(){return t.currentGuildId}});var s=I(a,2),i=y(s);{var o=c=>{Jb(c,{})};L(i,c=>{n()&&c(o)})}var l=I(i,2),u=y(l);mc(u,()=>t.children),E(e,r)}var jb=x('
    '),zb=x('
    '),Hb=x('

    No servers found. Make sure you have admin permissions in a server where Heimdallr is installed.

    '),$b=x('
    '),Qb=x('
    '),qb=x('

    '),ev=x('
    '),tv=x('

    Select a Server

    ');function nv(e,t){Y(t,!0);const n=_r(),r=jt();let a=j(null);Kt(async()=>{if(!r.user)try{const s=await ct.getCurrentUser({});s.user&&(r.user=s.user)}catch{In("/");return}n.loading=!0;try{const s=await ct.listGuilds({});n.guilds=s.guilds}catch(s){F(a,s.message,!0)}finally{n.loading=!1}}),Ya(e,{children:(s,i)=>{var o=tv(),l=I(y(o),2);{var u=b=>{var h=jb(),v=y(h),N=y(v);G(()=>D(N,d(a))),E(b,h)};L(l,b=>{d(a)&&b(u)})}var c=I(l,2);{var m=b=>{var h=zb();E(b,h)},p=b=>{var h=Hb();E(b,h)},f=b=>{var h=ev();ne(h,21,()=>n.guilds,te,(v,N)=>{var O=qb(),T=y(O),_=y(T);{var w=R=>{var V=$b(),U=y(V),Z=y(U);G(()=>{pe(Z,"src",`https://cdn.discordapp.com/icons/${d(N).id??""}/${d(N).icon??""}.png?size=128`),pe(Z,"alt",d(N).name)}),E(R,V)},A=R=>{var V=Qb(),U=y(V),Z=y(U),le=y(Z);G($=>D(le,$),[()=>d(N).name.charAt(0).toUpperCase()]),E(R,V)};L(_,R=>{d(N).icon?R(w):R(A,!1)})}var S=I(_,2),k=y(S);G(()=>{pe(O,"href",`/#/guild/${d(N).id??""}`),D(k,d(N).name)}),E(v,O)}),E(b,h)};L(c,b=>{n.loading?b(m):n.guilds.length===0?b(p,1):b(f,!1)})}E(s,o)},$$slots:{default:!0}}),B()}var rv=x('
    '),av=x('
    ');function sv(e,t){Y(t,!0);const n=jt(),r=_r(),a=dt();let s=j(!0);Kt(async()=>{if(!n.user)try{const i=await ct.getCurrentUser({});i.user&&(n.user=i.user)}catch{In("/");return}if(r.guilds.length===0)try{const i=await ct.listGuilds({});r.guilds=i.guilds}catch{}await a.loadAll(t.params.id),F(s,!1)}),Ya(e,{get currentGuildId(){return t.params.id},showSidebar:!0,children:(i,o)=>{var l=Ce(),u=q(l);{var c=p=>{var f=rv();E(p,f)},m=p=>{var f=av();ne(f,21,()=>Yl,te,(b,h)=>{const v=ae(()=>d(h).component);var N=Ce(),O=q(N);Jr(O,()=>d(v),(T,_)=>{_(T,{})}),E(b,N)}),E(p,f)};L(u,p=>{d(s)?p(c):p(m,!1)})}E(i,l)},$$slots:{default:!0}}),B()}var iv=x('
    '),ov=x(''),lv=x("
    "),uv=x('

    Components V2 Builder

    Send

    ');function cv(e,t){Y(t,!0);const n=jt(),r=_r();let a=j(!0),s=j(ie([])),i=j(""),o=j(!1),l=j(""),u=j(!1);Kt(async()=>{if(!n.user)try{const m=await ct.getCurrentUser({});m.user&&(n.user=m.user)}catch{In("/");return}if(r.guilds.length===0)try{const m=await ct.listGuilds({});r.guilds=m.guilds}catch{}F(a,!1)});async function c(){if(!d(i)){F(l,"Please select a channel"),F(u,!0);return}const m=Dl(d(s));if(JSON.parse(m).length===0){F(l,"Add at least one component with content"),F(u,!0);return}F(o,!0),F(l,"");try{const f=await ue.sendComponentsMessage({guildId:t.params.id,channelId:d(i),componentsJson:m});F(l,`Message sent! ID: ${f.messageId}`),F(u,!1)}catch(f){const b=f instanceof Error?f.message:"Unknown error";F(l,`Failed: ${b}`),F(u,!0)}finally{F(o,!1)}}Ya(e,{get currentGuildId(){return t.params.id},children:(m,p)=>{var f=Ce(),b=q(f);{var h=N=>{var O=iv();E(N,O)},v=N=>{var O=uv(),T=y(O),_=I(y(T),2);Cl(_,{get components(){return d(s)},set components(H){F(s,H,!0)}});var w=I(T,2),A=y(w);Ml(A,{get components(){return d(s)}});var S=I(A,2),k=y(S),R=I(y(k),2);bn(R,{label:"Target Channel",get value(){return d(i)},get guildId(){return t.params.id},onchange:H=>F(i,H,!0)});var V=I(R,2),U=y(V);{var Z=H=>{var _e=ov();E(H,_e)};L(U,H=>{d(o)&&H(Z)})}var le=I(V,2);{var $=H=>{var _e=lv();let Fe;var M=y(_e);G(()=>{Fe=Gt(_e,1,"text-sm",null,Fe,{"text-error":d(u),"text-success":!d(u)}),D(M,d(l))}),E(H,_e)};L(le,H=>{d(l)&&H($)})}G(()=>V.disabled=d(o)),P("click",V,c),E(N,O)};L(b,N=>{d(a)?N(h):N(v,!1)})}E(m,f)},$$slots:{default:!0}}),B()}ve(["click"]);function fv(e){const t={"/":Wc,"/callback":Gm,"/guilds":nv,"/guild/:id/sandbox":cv,"/guild/:id":sv};Uc(e,{get routes(){return t}})}oc(fv,{target:document.getElementById("app")}); diff --git a/heimdallr/rpcserver/frontend/assets/index-Dp-rUzZr.css b/heimdallr/rpcserver/frontend/assets/index-Dp-rUzZr.css new file mode 100644 index 0000000..7931fff --- /dev/null +++ b/heimdallr/rpcserver/frontend/assets/index-Dp-rUzZr.css @@ -0,0 +1 @@ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-3xl:48rem;--container-4xl:56rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-semibold:600;--font-weight-bold:700;--radius-lg:.5rem;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@media(prefers-color-scheme:dark){:root:not([data-theme]){color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}}:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E");scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab,red,red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}@property --radialprogress{syntax: ""; inherits: true; initial-value: 0%;}:root:not(span){overflow:var(--page-overflow)}:root{background:var(--page-scroll-bg,var(--root-bg));--page-scroll-bg-on:linear-gradient(var(--root-bg,#0000),var(--root-bg,#0000))var(--root-bg,#0000)}@supports (color:color-mix(in lab,red,red)){:root{--page-scroll-bg-on:linear-gradient(var(--root-bg,#0000),var(--root-bg,#0000))color-mix(in srgb,var(--root-bg,#0000),oklch(0% 0 0) calc(var(--page-has-backdrop,0)*40%))}}:root{--page-scroll-transition-on:background-color .3s ease-out;transition:var(--page-scroll-transition);scrollbar-gutter:var(--page-scroll-gutter,unset);scrollbar-gutter:if(style(--page-has-scroll: 1): var(--page-scroll-gutter,unset); else: unset)}@keyframes set-page-has-scroll{0%,to{--page-has-scroll:1}}:root,[data-theme]{background:var(--page-scroll-bg,var(--root-bg));color:var(--color-base-content)}:where(:root,[data-theme]){--root-bg:var(--color-base-100)}}@layer components;@layer utilities{@layer daisyui.l1.l2.l3{.modal{pointer-events:none;visibility:hidden;width:100%;max-width:none;height:100%;max-height:none;color:inherit;transition:visibility .3s allow-discrete,background-color .3s ease-out,opacity .1s ease-out;overscroll-behavior:contain;z-index:999;scrollbar-gutter:auto;background-color:#0000;place-items:center;margin:0;padding:0;display:grid;position:fixed;inset:0;overflow:clip}.modal::backdrop{display:none}.menu{--menu-active-fg:var(--color-neutral-content);--menu-active-bg:var(--color-neutral);flex-flow:column wrap;width:fit-content;padding:.5rem;font-size:.875rem;display:flex}.menu :where(li ul){white-space:nowrap;margin-inline-start:1rem;padding-inline-start:.5rem;position:relative}.menu :where(li ul):before{background-color:var(--color-base-content);opacity:.1;width:var(--border);content:"";inset-inline-start:0;position:absolute;top:.75rem;bottom:.75rem}.menu :where(li>.menu-dropdown:not(.menu-dropdown-show)){display:none}.menu :where(li:not(.menu-title)>:not(ul,details,.menu-title,.btn)),.menu :where(li:not(.menu-title)>details>summary:not(.menu-title)){border-radius:var(--radius-field);text-align:start;text-wrap:balance;-webkit-user-select:none;user-select:none;grid-auto-columns:minmax(auto,max-content) auto max-content;grid-auto-flow:column;align-content:flex-start;align-items:center;gap:.5rem;padding-block:.375rem;padding-inline:.75rem;transition-property:color,background-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:grid}.menu :where(li>details>summary){--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.menu :where(li>details>summary){outline-offset:2px;outline:2px solid #0000}}.menu :where(li>details>summary)::-webkit-details-marker{display:none}:is(.menu :where(li>details>summary),.menu :where(li>.menu-dropdown-toggle)):after{content:"";transform-origin:50%;pointer-events:none;justify-self:flex-end;width:.375rem;height:.375rem;transition-property:rotate,translate;transition-duration:.2s;display:block;translate:0 -1px;rotate:-135deg;box-shadow:inset 2px 2px}.menu details{interpolate-size:allow-keywords;overflow:hidden}.menu details::details-content{block-size:0}@media(prefers-reduced-motion:no-preference){.menu details::details-content{transition-behavior:allow-discrete;transition-property:block-size,content-visibility;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}}.menu details[open]::details-content{block-size:auto}.menu :where(li>details[open]>summary):after,.menu :where(li>.menu-dropdown-toggle.menu-dropdown-show):after{translate:0 1px;rotate:45deg}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{cursor:pointer;background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{color:var(--color-base-content);--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{outline-offset:2px;outline:2px solid #0000}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){cursor:pointer;background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){outline-offset:2px;outline:2px solid #0000}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){box-shadow:inset 0 1px #00000003,inset 0 -1px #ffffff03}.menu :where(li:empty){background-color:var(--color-base-content);opacity:.1;height:1px;margin:.5rem 1rem}.menu :where(li){flex-flow:column wrap;flex-shrink:0;align-items:stretch;display:flex;position:relative}.menu :where(li) .badge{justify-self:flex-end}.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active{outline-offset:2px;outline:2px solid #0000}}.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active{color:var(--menu-active-fg);background-color:var(--menu-active-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise)}:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):not(:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):active){box-shadow:0 2px calc(var(--depth)*3px) -2px var(--menu-active-bg)}.menu :where(li).menu-disabled{pointer-events:none;color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.menu :where(li).menu-disabled{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.menu .dropdown:focus-within .menu-dropdown-toggle:after{translate:0 1px;rotate:45deg}.menu .dropdown-content{margin-top:.5rem;padding:.5rem}.menu .dropdown-content:before{display:none}.dropdown{position-area:var(--anchor-v,bottom)var(--anchor-h,span-right);display:inline-block;position:relative}.dropdown>:not(:has(~[class*=dropdown-content])):focus{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.dropdown>:not(:has(~[class*=dropdown-content])):focus{outline-offset:2px;outline:2px solid #0000}}.dropdown .dropdown-content{position:absolute}.dropdown.dropdown-close .dropdown-content,.dropdown:not(details,.dropdown-open,.dropdown-hover:hover,:focus-within) .dropdown-content,.dropdown.dropdown-hover:not(:hover) [tabindex]:first-child:focus:not(:focus-visible)~.dropdown-content{transform-origin:top;opacity:0;display:none;scale:95%}.dropdown[popover],.dropdown .dropdown-content{z-index:999}@media(prefers-reduced-motion:no-preference){.dropdown[popover],.dropdown .dropdown-content{transition-behavior:allow-discrete;transition-property:opacity,scale,display;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation:.2s dropdown}}@starting-style{.dropdown[popover],.dropdown .dropdown-content{opacity:0;scale:95%}}:is(.dropdown:not(.dropdown-close).dropdown-open,.dropdown:not(.dropdown-close):not(.dropdown-hover):focus,.dropdown:not(.dropdown-close):focus-within)>[tabindex]:first-child{pointer-events:none}:is(.dropdown:not(.dropdown-close).dropdown-open,.dropdown:not(.dropdown-close):not(.dropdown-hover):focus,.dropdown:not(.dropdown-close):focus-within) .dropdown-content,.dropdown:not(.dropdown-close).dropdown-hover:hover .dropdown-content{opacity:1;scale:100%}.dropdown:is(details) summary::-webkit-details-marker{display:none}.dropdown:where([popover]){background:0 0}.dropdown[popover]{color:inherit;position:fixed}@supports not (position-area:bottom){.dropdown[popover]{margin:auto}.dropdown[popover].dropdown-close{transform-origin:top;opacity:0;display:none;scale:95%}.dropdown[popover].dropdown-open:not(:popover-open){transform-origin:top;opacity:0;display:none;scale:95%}.dropdown[popover]::backdrop{background-color:oklab(0% none none/.3)}}:is(.dropdown[popover].dropdown-close,.dropdown[popover]:not(.dropdown-open,:popover-open)){transform-origin:top;opacity:0;display:none;scale:95%}:where(.btn){width:unset}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%)) inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}@supports (color:color-mix(in lab,red,red)){.btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%))}}.btn{--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg)}@supports (color:color-mix(in lab,red,red)){.btn{--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.btn{--btn-noise:var(--fx-noise)}@media(hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab,red,red)){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.btn:focus-visible,.btn:has(:focus-visible){isolation:isolate;outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));translate:0 .5px}@supports (color:color-mix(in lab,red,red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%)}}.btn:active:not(.btn-active){--btn-border:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab,red,red)){.btn:active:not(.btn-active){--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:active:not(.btn-active){--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0)}.btn:is(input[type=checkbox],input[type=radio]){appearance:none}.btn:is(input[type=checkbox],input[type=radio])[aria-label]:after{--tw-content:attr(aria-label);content:var(--tw-content)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem)*6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.list{flex-direction:column;font-size:.875rem;display:flex}.list .list-row{--list-grid-cols:minmax(0,auto)1fr;border-radius:var(--radius-box);word-break:break-word;grid-auto-flow:column;grid-template-columns:var(--list-grid-cols);gap:1rem;padding:1rem;display:grid;position:relative}:is(.list>:not(:last-child).list-row,.list>:not(:last-child) .list-row):after{content:"";border-bottom:var(--border)solid;inset-inline:var(--radius-box);border-color:var(--color-base-content);position:absolute;bottom:0}@supports (color:color-mix(in lab,red,red)){:is(.list>:not(:last-child).list-row,.list>:not(:last-child) .list-row):after{border-color:color-mix(in oklab,var(--color-base-content)5%,transparent)}}.toggle{border:var(--border)solid currentColor;color:var(--input-color);cursor:pointer;appearance:none;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--toggle-p),var(--radius-selector-max)) + min(var(--border),var(--radius-selector-max)));padding:var(--toggle-p);flex-shrink:0;grid-template-columns:0fr 1fr 1fr;place-content:center;display:inline-grid;position:relative;box-shadow:inset 0 1px}@supports (color:color-mix(in lab,red,red)){.toggle{box-shadow:0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000) inset}}.toggle{--input-color:var(--color-base-content);transition:color .3s,grid-template-columns .2s}@supports (color:color-mix(in lab,red,red)){.toggle{--input-color:color-mix(in oklab,var(--color-base-content)50%,#0000)}}.toggle{--toggle-p:calc(var(--size)*.125);--size:calc(var(--size-selector,.25rem)*6);width:calc((var(--size)*2) - (var(--border) + var(--toggle-p))*2);height:var(--size)}.toggle>*{z-index:1;cursor:pointer;appearance:none;background-color:#0000;border:none;grid-column:2/span 1;grid-row-start:1;height:100%;padding:.125rem;transition:opacity .2s,rotate .4s}.toggle>:focus{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.toggle>:focus{outline-offset:2px;outline:2px solid #0000}}.toggle>:nth-child(2){color:var(--color-base-100);rotate:none}.toggle>:nth-child(3){color:var(--color-base-100);opacity:0;rotate:-15deg}.toggle:has(:checked)>:nth-child(2){opacity:0;rotate:15deg}.toggle:has(:checked)>:nth-child(3){opacity:1;rotate:none}.toggle:before{aspect-ratio:1;border-radius:var(--radius-selector);--tw-content:"";content:var(--tw-content);width:100%;height:100%;box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor;background-color:currentColor;grid-row-start:1;grid-column-start:2;transition:background-color .1s,translate .2s,inset-inline-start .2s;position:relative;inset-inline-start:0;translate:0}@supports (color:color-mix(in lab,red,red)){.toggle:before{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000)}}.toggle:before{background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise)}@media(forced-colors:active){.toggle:before{outline-style:var(--tw-outline-style);outline-offset:-1px;outline-width:1px}}@media print{.toggle:before{outline-offset:-1rem;outline:.25rem solid}}.toggle:focus-visible,.toggle:has(:focus-visible){outline-offset:2px;outline:2px solid}.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked){background-color:var(--color-base-100);--input-color:var(--color-base-content);grid-template-columns:1fr 1fr 0fr}:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{background-color:currentColor}@starting-style{:is(.toggle:checked,.toggle[aria-checked=true],.toggle:has(>input:checked)):before{opacity:0}}.toggle:indeterminate{grid-template-columns:.5fr 1fr .5fr}.toggle:disabled{cursor:not-allowed;opacity:.3}.toggle:disabled:before{border:var(--border)solid currentColor;background-color:#0000}.input{cursor:text;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);font-size:max(var(--font-size,.875rem),.875rem);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab,red,red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.input{--size:calc(var(--size-field,.25rem)*10);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-flex}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.input:focus,.input:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:focus,.input:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@media(pointer:coarse){@supports (-webkit-touch-callout:none){.input:focus,.input:focus-within{--font-size:1rem}}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.input:has(>input[type=date]) :where(input[type=date]){webkit-appearance:none;appearance:none;display:inline-flex}.input:has(>input[type=date]) input[type=date]::-webkit-calendar-picker-indicator{cursor:pointer;width:1em;height:1em;position:absolute;inset-inline-end:.75em}.range{appearance:none;webkit-appearance:none;--range-thumb:var(--color-base-100);--range-thumb-size:calc(var(--size-selector,.25rem)*6);--range-progress:currentColor;--range-fill:1;--range-p:.25rem;--range-bg:currentColor}@supports (color:color-mix(in lab,red,red)){.range{--range-bg:color-mix(in oklab,currentColor 10%,#0000)}}.range{cursor:pointer;vertical-align:middle;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));width:clamp(3rem,20rem,100%);height:var(--range-thumb-size);background-color:#0000;border:none;overflow:hidden}[dir=rtl] .range{--range-dir:-1}.range:focus{outline:none}.range:focus-visible{outline-offset:2px;outline:2px solid}.range::-webkit-slider-runnable-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}@media(forced-colors:active){.range::-webkit-slider-runnable-track{border:1px solid}.range::-moz-range-track{border:1px solid}}.range::-webkit-slider-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));background-color:var(--range-thumb);height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;appearance:none;webkit-appearance:none;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100cqw) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100cqw*var(--range-fill));position:relative;top:50%;transform:translateY(-50%)}@supports (color:color-mix(in lab,red,red)){.range::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100cqw) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100cqw*var(--range-fill))}}.range::-moz-range-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}.range::-moz-range-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px currentColor,0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100cqw) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100cqw*var(--range-fill));background-color:currentColor;position:relative;top:50%}@supports (color:color-mix(in lab,red,red)){.range::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb) inset,calc((var(--range-dir,1)*-100cqw) - (var(--range-dir,1)*var(--range-thumb-size)/2)) 0 0 calc(100cqw*var(--range-fill))}}.range:disabled{cursor:not-allowed;opacity:.3}.select{border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;white-space:nowrap;text-overflow:ellipsis;box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-image:linear-gradient(45deg,#0000 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,#0000 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-repeat:no-repeat;background-size:4px 4px,4px 4px;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.375rem;padding-inline:.75rem 1.75rem;font-size:.875rem;display:inline-flex;position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.select{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.select{border-color:var(--input-color);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.select{--size:calc(var(--size-field,.25rem)*10)}[dir=rtl] .select{background-position:12px calc(1px + 50%),16px calc(1px + 50%)}[dir=rtl] .select::picker(select){translate:.5rem}[dir=rtl] .select select::picker(select){translate:.5rem}.select[multiple]{background-image:none;height:auto;padding-block:.75rem;padding-inline-end:.75rem;overflow:auto}.select select{appearance:none;width:calc(100% + 2.75rem);height:calc(100% - calc(var(--border)*2));background:inherit;border-radius:inherit;border-style:none;align-items:center;margin-inline:-.75rem -1.75rem;padding-inline:.75rem 1.75rem}.select select:focus,.select select:focus-within{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.select select:focus,.select select:focus-within{outline-offset:2px;outline:2px solid #0000}}.select select:not(:last-child){background-image:none;margin-inline-end:-1.375rem}.select:focus,.select:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.select:focus,.select:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.select:focus,.select:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select)::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select)::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.select:has(>select[disabled])>select[disabled]{cursor:not-allowed}@supports (appearance:base-select){.select,.select select{appearance:base-select}:is(.select,.select select)::picker(select){appearance:base-select}}:is(.select,.select select)::picker(select){color:inherit;border:var(--border)solid var(--color-base-200);border-radius:var(--radius-box);background-color:inherit;max-height:min(24rem,70dvh);box-shadow:0 2px calc(var(--depth)*3px) -2px #0003;box-shadow:0 20px 25px -5px rgb(0 0 0/calc(var(--depth)*.1)),0 8px 10px -6px rgb(0 0 0/calc(var(--depth)*.1));margin-block:.5rem;margin-inline:.5rem;padding:.5rem;translate:-.5rem}:is(.select,.select select)::picker-icon{display:none}:is(.select,.select select) optgroup{padding-top:.5em}:is(.select,.select select) optgroup option:first-child{margin-top:.5em}:is(.select,.select select) option{border-radius:var(--radius-field);white-space:normal;padding-block:.375rem;padding-inline:.75rem;transition-property:color,background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{cursor:pointer;background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{outline-offset:2px;outline:2px solid #0000}}:is(.select,.select select) option:not(:disabled):active{background-color:var(--color-neutral);color:var(--color-neutral-content);box-shadow:0 2px calc(var(--depth)*3px) -2px var(--color-neutral)}.avatar{vertical-align:middle;display:inline-flex;position:relative}.avatar>div{aspect-ratio:1;display:block;overflow:hidden}.avatar img{object-fit:cover;width:100%;height:100%}.checkbox{border:var(--border)solid var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab,red,red)){.checkbox{border:var(--border)solid var(--input-color,color-mix(in oklab,var(--color-base-content)20%,#0000))}}.checkbox{cursor:pointer;appearance:none;border-radius:var(--radius-selector);vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0% 0 0/calc(var(--depth)*.1)) inset,0 0 #0000 inset,0 0 #0000;--size:calc(var(--size-selector,.25rem)*6);width:var(--size);height:var(--size);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);flex-shrink:0;padding:.25rem;transition:background-color .2s,box-shadow .2s;display:inline-block;position:relative}.checkbox:before{--tw-content:"";content:var(--tw-content);opacity:0;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);width:100%;height:100%;box-shadow:0 3px oklch(100% 0 0/calc(var(--depth)*.1)) inset;background-color:currentColor;font-size:1rem;line-height:.75;transition:clip-path .3s .1s,opacity .1s .1s,rotate .3s .1s,translate .3s .1s;display:block;rotate:45deg}.checkbox:focus-visible{outline:2px solid var(--input-color,currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color,#0000);box-shadow:0 0 #0000 inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0% 0 0/calc(var(--depth)*.1))}:is(.checkbox:checked,.checkbox[aria-checked=true]):before{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:1}@media(forced-colors:active){:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}@media print{:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:none}}.checkbox:indeterminate{background-color:var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab,red,red)){.checkbox:indeterminate{background-color:var(--input-color,color-mix(in oklab,var(--color-base-content)20%,#0000))}}.checkbox:indeterminate:before{opacity:1;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%);translate:0 -35%;rotate:none}.navbar{align-items:center;width:100%;min-height:4rem;padding:.5rem;display:flex}.card{border-radius:var(--radius-box);outline-offset:2px;outline:0 solid #0000;flex-direction:column;transition:outline .2s ease-in-out;display:flex;position:relative}.card:focus{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.card:focus{outline-offset:2px;outline:2px solid #0000}}.card:focus-visible{outline-color:currentColor}.card :where(figure:first-child){border-start-start-radius:inherit;border-start-end-radius:inherit;border-end-end-radius:unset;border-end-start-radius:unset;overflow:hidden}.card :where(figure:last-child){border-start-start-radius:unset;border-start-end-radius:unset;border-end-end-radius:inherit;border-end-start-radius:inherit;overflow:hidden}.card figure{justify-content:center;align-items:center;display:flex}.card:has(>input:is(input[type=checkbox],input[type=radio])){cursor:pointer;-webkit-user-select:none;user-select:none}.card:has(>:checked){outline:2px solid}.hero-content{isolation:isolate;justify-content:center;align-items:center;gap:1rem;max-width:80rem;padding:1rem;display:flex}.textarea{border:var(--border)solid #0000;appearance:none;border-radius:var(--radius-field);background-color:var(--color-base-100);vertical-align:middle;width:clamp(3rem,20rem,100%);min-height:5rem;font-size:max(var(--font-size,.875rem),.875rem);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;flex-shrink:1;padding-block:.5rem;padding-inline:.75rem}@supports (color:color-mix(in lab,red,red)){.textarea{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset}}.textarea{--input-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.textarea textarea{appearance:none;background-color:#0000;border:none}.textarea textarea:focus,.textarea textarea:focus-within{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.textarea textarea:focus,.textarea textarea:focus-within{outline-offset:2px;outline:2px solid #0000}}.textarea:focus,.textarea:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab,red,red)){.textarea:focus,.textarea:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.textarea:focus,.textarea:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@media(pointer:coarse){@supports (-webkit-touch-callout:none){.textarea:focus,.textarea:focus-within{--font-size:1rem}}}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){:is(.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.textarea:has(>textarea[disabled]),.textarea:is(:disabled,[disabled]){box-shadow:none}.textarea:has(>textarea[disabled])>textarea[disabled]{cursor:not-allowed}.modal-backdrop{color:#0000;z-index:-1;grid-row-start:1;grid-column-start:1;place-self:stretch stretch;display:grid}.modal-backdrop button{cursor:pointer}.hero{background-position:50%;background-size:cover;place-items:center;width:100%;display:grid}.hero>*{grid-row-start:1;grid-column-start:1}.modal-box{background-color:var(--color-base-100);border-top-left-radius:var(--modal-tl,var(--radius-box));border-top-right-radius:var(--modal-tr,var(--radius-box));border-bottom-left-radius:var(--modal-bl,var(--radius-box));border-bottom-right-radius:var(--modal-br,var(--radius-box));opacity:0;overscroll-behavior:contain;grid-row-start:1;grid-column-start:1;width:91.6667%;max-width:32rem;max-height:100vh;padding:1.5rem;transition:translate .3s ease-out,scale .3s ease-out,opacity .2s ease-out 50ms,box-shadow .3s ease-out;overflow-y:auto;scale:95%;box-shadow:0 25px 50px -12px #00000040}.divider{white-space:nowrap;height:1rem;margin:var(--divider-m,1rem 0);--divider-color:var(--color-base-content);flex-direction:row;align-self:stretch;align-items:center;display:flex}@supports (color:color-mix(in lab,red,red)){.divider{--divider-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.divider:before,.divider:after{content:"";background-color:var(--divider-color);flex-grow:1;width:100%;height:.125rem}@media print{.divider:before,.divider:after{border:.5px solid}}.divider:not(:empty){gap:1rem}.label{white-space:nowrap;color:currentColor;align-items:center;gap:.375rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.label{color:color-mix(in oklab,currentcolor 60%,transparent)}}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){white-space:nowrap;height:calc(100% - .5rem);font-size:inherit;align-items:center;padding-inline:.75rem;display:flex}.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid currentColor;margin-inline:-.75rem .75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid currentColor;margin-inline:.75rem -.75rem}@supports (color:color-mix(in lab,red,red)){.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.modal-action{justify-content:flex-end;gap:.5rem;margin-top:1.5rem;display:flex}.badge{border-radius:var(--radius-selector);vertical-align:middle;color:var(--badge-fg);border:var(--border)solid var(--badge-color,var(--color-base-200));background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);background-color:var(--badge-bg);--badge-bg:var(--badge-color,var(--color-base-100));--badge-fg:var(--color-base-content);--size:calc(var(--size-selector,.25rem)*6);width:fit-content;height:var(--size);padding-inline:calc(var(--size)/2 - var(--border));justify-content:center;align-items:center;gap:.5rem;font-size:.875rem;display:inline-flex}.kbd{border-radius:var(--radius-field);background-color:var(--color-base-200);vertical-align:middle;border:var(--border)solid var(--color-base-content);justify-content:center;align-items:center;padding-inline:.5em;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.kbd{border:var(--border)solid color-mix(in srgb,var(--color-base-content)20%,#0000)}}.kbd{border-bottom:calc(var(--border) + 1px)solid var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.kbd{border-bottom:calc(var(--border) + 1px)solid color-mix(in srgb,var(--color-base-content)20%,#0000)}}.kbd{--size:calc(var(--size-selector,.25rem)*6);height:var(--size);min-width:var(--size);font-size:.875rem}.footer{grid-auto-flow:row;place-items:start;gap:2.5rem 1rem;width:100%;font-size:.875rem;line-height:1.25rem;display:grid}.footer>*{place-items:start;gap:.5rem;display:grid}.footer.footer-center{text-align:center;grid-auto-flow:column dense;place-items:center}.footer.footer-center>*{place-items:center}.card-body{padding:var(--card-p,1.5rem);font-size:var(--card-fs,.875rem);flex-direction:column;flex:auto;gap:.5rem;display:flex}.card-body :where(p){flex-grow:1}.alert{--alert-border-color:var(--color-base-200);border-radius:var(--radius-box);color:var(--color-base-content);background-color:var(--alert-color,var(--color-base-200));text-align:start;background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08)) inset,0 1px #000,0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08));border-style:solid;grid-template-columns:auto;grid-auto-flow:column;justify-content:start;place-items:center start;gap:1rem;padding-block:.75rem;padding-inline:1rem;font-size:.875rem;line-height:1.25rem;display:grid}@supports (color:color-mix(in lab,red,red)){.alert{box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08)) inset,0 1px color-mix(in oklab,color-mix(in oklab,#000 20%,var(--alert-color,var(--color-base-200)))calc(var(--depth)*20%),#0000),0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08))}}.alert:has(:nth-child(2)){grid-template-columns:auto minmax(auto,1fr)}.card-title{font-size:var(--cardtitle-fs,1.125rem);align-items:center;gap:.5rem;font-weight:600;display:flex}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media(forced-colors:active){.link:focus{outline-offset:2px;outline:2px solid #0000}}.link:focus-visible{outline-offset:2px;outline:2px solid}.menu-title{color:var(--color-base-content);padding-block:.5rem;padding-inline:.75rem}@supports (color:color-mix(in lab,red,red)){.menu-title{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}.menu-title{font-size:.875rem;font-weight:600}.btn-error{--btn-color:var(--color-error);--btn-fg:var(--color-error-content)}.btn-neutral{--btn-color:var(--color-neutral);--btn-fg:var(--color-neutral-content)}.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}.btn-success{--btn-color:var(--color-success);--btn-fg:var(--color-success-content)}}@layer daisyui.l1.l2{.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal{pointer-events:auto;visibility:visible;opacity:1;transition:visibility 0s allow-discrete,background-color .3s ease-out,opacity .1s ease-out;background-color:#0006}:is(.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal) .modal-box{opacity:1;translate:0;scale:1}:root:has(:is(.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal)){--page-has-backdrop:1;--page-overflow:hidden;--page-scroll-bg:var(--page-scroll-bg-on);--page-scroll-gutter:stable;--page-scroll-transition:var(--page-scroll-transition-on);animation:forwards set-page-has-scroll;animation-timeline:scroll()}@starting-style{.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal{opacity:0}}.btn:disabled:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn:disabled:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.btn:disabled:not(.btn-link,.btn-ghost){box-shadow:none}.btn:disabled{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn:disabled{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.btn[disabled]:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn[disabled]:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.btn[disabled]:not(.btn-link,.btn-ghost){box-shadow:none}.btn[disabled]{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.btn[disabled]{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.list .list-row:has(.list-col-grow:first-child){--list-grid-cols:1fr}.list .list-row:has(.list-col-grow:nth-child(2)){--list-grid-cols:minmax(0,auto)1fr}.list .list-row:has(.list-col-grow:nth-child(3)){--list-grid-cols:minmax(0,auto)minmax(0,auto)1fr}.list .list-row:has(.list-col-grow:nth-child(4)){--list-grid-cols:minmax(0,auto)minmax(0,auto)minmax(0,auto)1fr}.list .list-row:has(.list-col-grow:nth-child(5)){--list-grid-cols:minmax(0,auto)minmax(0,auto)minmax(0,auto)minmax(0,auto)1fr}.list .list-row:has(.list-col-grow:nth-child(6)){--list-grid-cols:minmax(0,auto)minmax(0,auto)minmax(0,auto)minmax(0,auto)minmax(0,auto)1fr}.list .list-row>*{grid-row-start:1}.checkbox:disabled{cursor:not-allowed;opacity:.2}:where(.navbar){position:relative}.dropdown-end{--anchor-h:span-left}.dropdown-end :where(.dropdown-content){inset-inline-end:0;translate:0}[dir=rtl] :is(.dropdown-end :where(.dropdown-content)){translate:0}.dropdown-end.dropdown-left{--anchor-h:left;--anchor-v:span-top}.dropdown-end.dropdown-left .dropdown-content{top:auto;bottom:0}.dropdown-end.dropdown-right{--anchor-h:right;--anchor-v:span-top}.dropdown-end.dropdown-right .dropdown-content{top:auto;bottom:0}.input-sm{--size:calc(var(--size-field,.25rem)*8);font-size:max(var(--font-size,.75rem),.75rem)}.input-sm[type=number]::-webkit-inner-spin-button{margin-block:-.5rem;margin-inline-end:-.75rem}.btn-circle{width:var(--size);height:var(--size);border-radius:3.40282e38px;padding-inline:0}.btn-square{width:var(--size);height:var(--size);padding-inline:0}.loading-lg{width:calc(var(--size-selector,.25rem)*7)}.loading-md{width:calc(var(--size-selector,.25rem)*6)}.loading-sm{width:calc(var(--size-selector,.25rem)*5)}.loading-xs{width:calc(var(--size-selector,.25rem)*4)}.badge-outline{color:var(--badge-color);--badge-bg:#0000;background-image:none;border-color:currentColor}.loading-dots{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E")}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.select-sm{--size:calc(var(--size-field,.25rem)*8);font-size:.75rem}.select-sm option{padding-block:.25rem;padding-inline:.625rem}.badge-sm,.kbd-sm{--size:calc(var(--size-selector,.25rem)*5);font-size:.75rem}.textarea-sm{font-size:max(var(--font-size,.75rem),.75rem)}.alert-error{color:var(--color-error-content);--alert-border-color:var(--color-error);--alert-color:var(--color-error)}.btn-sm{--fontsize:.75rem;--btn-p:.75rem;--size:calc(var(--size-field,.25rem)*8)}.btn-xs{--fontsize:.6875rem;--btn-p:.5rem;--size:calc(var(--size-field,.25rem)*6)}.toggle-primary:checked,.toggle-primary[aria-checked=true]{--input-color:var(--color-primary)}.toggle-sm[type=checkbox],.toggle-sm:has([type=checkbox]){--size:calc(var(--size-selector,.25rem)*5)}}.prose :where(a.btn:not(.btn-link)):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-line:none}.relative{position:relative}.join{--join-ss:0;--join-se:0;--join-es:0;--join-ee:0;align-items:stretch;display:inline-flex}.join :where(.join-item){border-start-start-radius:var(--join-ss,0);border-start-end-radius:var(--join-se,0);border-end-end-radius:var(--join-ee,0);border-end-start-radius:var(--join-es,0)}.join :where(.join-item) *{--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>.join-item:where(:first-child),.join :first-child:not(:last-child) :where(.join-item){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join>.join-item:where(:last-child),.join :last-child:not(:first-child) :where(.join-item){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join>.join-item:where(:only-child),.join :only-child :where(.join-item){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>:where(:focus,:has(:focus)){z-index:1}@media(hover:hover){.join>:where(.btn:hover,:has(.btn:hover)){isolation:isolate}}.z-10{z-index:10}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-3{margin-block:calc(var(--spacing)*3)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1{margin-right:calc(var(--spacing)*1)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-2{margin-left:calc(var(--spacing)*2)}.kbd{box-shadow:none}.alert{border-width:var(--border);border-color:var(--alert-border-color,var(--color-base-200))}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-2{height:calc(var(--spacing)*2)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-16{height:calc(var(--spacing)*16)}.h-32{height:calc(var(--spacing)*32)}.h-\[90vh\]{height:90vh}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-screen{min-height:100vh}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-16{width:calc(var(--spacing)*16)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-52{width:calc(var(--spacing)*52)}.w-56{width:calc(var(--spacing)*56)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-48{max-width:calc(var(--spacing)*48)}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.flex-1{flex:1}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-start{align-self:flex-start}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-box{border-radius:var(--radius-box)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-base-300{border-color:var(--color-base-300)}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.bg-base-300{background-color:var(--color-base-300)}.bg-neutral{background-color:var(--color-neutral)}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-12{padding-block:calc(var(--spacing)*12)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre-wrap{white-space:pre-wrap}.text-base-content\/40{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.text-base-content\/40{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}.text-base-content\/50{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.text-base-content\/50{color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.text-base-content\/60{color:var(--color-base-content)}@supports (color:color-mix(in lab,red,red)){.text-base-content\/60{color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.text-error{color:var(--color-error)}.text-neutral-content{color:var(--color-neutral-content)}.text-success{color:var(--color-success)}@layer daisyui.l1{.btn-link{--btn-border:#0000;--btn-bg:#0000;--btn-noise:none;--btn-shadow:"";outline-color:currentColor;text-decoration-line:underline}.btn-link:not(.btn-disabled,.btn:disabled,.btn[disabled]){--btn-fg:var(--btn-color,var(--color-primary))}.btn-link:is(.btn-active,:hover,:active:focus,:focus-visible){--btn-border:#0000;--btn-bg:#0000}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible,input:checked:not(.filter .btn)){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible,input:checked:not(.filter .btn)):not(:disabled,[disabled],.btn-disabled){--btn-fg:var(--btn-color,currentColor);outline-color:currentColor}@media(hover:none){.btn-ghost:not(.btn-active,:active,:focus-visible,input:checked:not(.filter .btn)):hover{--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color,currentColor);--btn-border:#0000;--btn-noise:none;outline-color:currentColor}}.btn-outline:not(.btn-active,:hover,:active:focus,:focus-visible,input:checked:not(.filter .btn),:disabled,[disabled],.btn-disabled){--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color);--btn-border:var(--btn-color);--btn-noise:none}@media(hover:none){.btn-outline:not(.btn-active,:active,:focus-visible,input:checked:not(.filter .btn)):hover{--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color);--btn-border:var(--btn-color);--btn-noise:none}}}.opacity-60{opacity:.6}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.blur-sm{--tw-blur:blur(var(--blur-sm));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:block{display:block}.lg\:w-96{width:calc(var(--spacing)*96)}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}}}@keyframes rating{0%,40%{filter:brightness(1.05)contrast(1.05);scale:1.1}}@keyframes dropdown{0%{opacity:0}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes toast{0%{opacity:0;scale:.9}to{opacity:1;scale:1}}@keyframes rotator{89.9999%,to{--first-item-position:0 0%}90%,99.9999%{--first-item-position:0 calc(var(--items)*100%)}to{translate:0 -100%}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@keyframes menu{0%{opacity:0}}@keyframes progress{50%{background-position-x:-115%}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false} diff --git a/heimdallr/rpcserver/frontend/index.html b/heimdallr/rpcserver/frontend/index.html new file mode 100644 index 0000000..f18924c --- /dev/null +++ b/heimdallr/rpcserver/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + Heimdallr Dashboard + + + + +
    + + diff --git a/heimdallr/rpcserver/guild_settings_service.go b/heimdallr/rpcserver/guild_settings_service.go new file mode 100644 index 0000000..2f57bd6 --- /dev/null +++ b/heimdallr/rpcserver/guild_settings_service.go @@ -0,0 +1,573 @@ +//go:build web + +package rpcserver + +import ( + "context" + "encoding/json" + "errors" + "log/slog" + "strconv" + "strings" + + "connectrpc.com/connect" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" + + heimdallrv1 "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1" + "github.com/NLLCommunity/heimdallr/model" + "github.com/NLLCommunity/heimdallr/utils" +) + +type guildSettingsService struct { + client *bot.Client +} + +// isGuildAdmin checks whether a user has admin permission in a guild. +// It checks guild ownership first, then tries the member cache, then falls +// back to the REST API. +func isGuildAdmin(client *bot.Client, guild discord.Guild, userID snowflake.ID) bool { + if guild.OwnerID == userID { + return true + } + + member, ok := client.Caches.Member(guild.ID, userID) + if !ok { + m, err := client.Rest.GetMember(guild.ID, userID) + if err != nil { + return false + } + member = *m + } + + perms := client.Caches.MemberPermissions(member) + return perms.Has(discord.PermissionAdministrator) +} + +// checkGuildAdmin verifies the session user has admin permission in the given guild. +func checkGuildAdmin(ctx context.Context, client *bot.Client, guildIDStr string) (snowflake.ID, error) { + session := SessionFromContext(ctx) + if session == nil { + return 0, connect.NewError(connect.CodeUnauthenticated, nil) + } + + guildID, err := snowflake.Parse(guildIDStr) + if err != nil { + return 0, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid guild ID")) + } + + guild, ok := client.Caches.Guild(guildID) + if !ok { + return 0, connect.NewError(connect.CodePermissionDenied, errors.New("bot is not in this guild")) + } + + if !isGuildAdmin(client, guild, session.UserID) { + return 0, connect.NewError(connect.CodePermissionDenied, errors.New("you do not have administrator permission in this guild")) + } + + return guildID, nil +} + +func idStr(id snowflake.ID) string { + if id == 0 { + return "" + } + return id.String() +} + +func parseSnowflake(s string) snowflake.ID { + if s == "" { + return 0 + } + v, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return 0 + } + return snowflake.ID(v) +} + +// --- ModChannel --- + +func (s *guildSettingsService) GetModChannel(ctx context.Context, req *heimdallrv1.GetModChannelRequest) (*heimdallrv1.ModChannelSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.ModChannelSettings{ + GuildId: guildID.String(), + ModeratorChannel: idStr(settings.ModeratorChannel), + }, nil +} + +func (s *guildSettingsService) UpdateModChannel(ctx context.Context, req *heimdallrv1.UpdateModChannelRequest) (*heimdallrv1.ModChannelSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.ModeratorChannel = parseSnowflake(proto.GetModeratorChannel()) + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.ModChannelSettings{ + GuildId: guildID.String(), + ModeratorChannel: idStr(settings.ModeratorChannel), + }, nil +} + +// --- InfractionSettings --- + +func (s *guildSettingsService) GetInfractionSettings(ctx context.Context, req *heimdallrv1.GetInfractionSettingsRequest) (*heimdallrv1.InfractionSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.InfractionSettings{ + GuildId: guildID.String(), + HalfLifeDays: settings.InfractionHalfLifeDays, + NotifyOnWarnedUserJoin: settings.NotifyOnWarnedUserJoin, + NotifyWarnSeverityThreshold: settings.NotifyWarnSeverityThreshold, + }, nil +} + +func (s *guildSettingsService) UpdateInfractionSettings(ctx context.Context, req *heimdallrv1.UpdateInfractionSettingsRequest) (*heimdallrv1.InfractionSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.InfractionHalfLifeDays = proto.GetHalfLifeDays() + settings.NotifyOnWarnedUserJoin = proto.GetNotifyOnWarnedUserJoin() + settings.NotifyWarnSeverityThreshold = proto.GetNotifyWarnSeverityThreshold() + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.InfractionSettings{ + GuildId: guildID.String(), + HalfLifeDays: settings.InfractionHalfLifeDays, + NotifyOnWarnedUserJoin: settings.NotifyOnWarnedUserJoin, + NotifyWarnSeverityThreshold: settings.NotifyWarnSeverityThreshold, + }, nil +} + +// --- GatekeepSettings --- + +func (s *guildSettingsService) GetGatekeepSettings(ctx context.Context, req *heimdallrv1.GetGatekeepSettingsRequest) (*heimdallrv1.GatekeepSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.GatekeepSettings{ + GuildId: guildID.String(), + Enabled: settings.GatekeepEnabled, + PendingRole: idStr(settings.GatekeepPendingRole), + ApprovedRole: idStr(settings.GatekeepApprovedRole), + AddPendingRoleOnJoin: settings.GatekeepAddPendingRoleOnJoin, + ApprovedMessage: settings.GatekeepApprovedMessage, + ApprovedMessageV2: settings.GatekeepApprovedMessageV2, + ApprovedMessageV2Json: settings.GatekeepApprovedMessageV2Json, + }, nil +} + +func (s *guildSettingsService) UpdateGatekeepSettings(ctx context.Context, req *heimdallrv1.UpdateGatekeepSettingsRequest) (*heimdallrv1.GatekeepSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.GatekeepEnabled = proto.GetEnabled() + settings.GatekeepPendingRole = parseSnowflake(proto.GetPendingRole()) + settings.GatekeepApprovedRole = parseSnowflake(proto.GetApprovedRole()) + settings.GatekeepAddPendingRoleOnJoin = proto.GetAddPendingRoleOnJoin() + settings.GatekeepApprovedMessage = proto.GetApprovedMessage() + settings.GatekeepApprovedMessageV2 = proto.GetApprovedMessageV2() + settings.GatekeepApprovedMessageV2Json = proto.GetApprovedMessageV2Json() + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.GatekeepSettings{ + GuildId: guildID.String(), + Enabled: settings.GatekeepEnabled, + PendingRole: idStr(settings.GatekeepPendingRole), + ApprovedRole: idStr(settings.GatekeepApprovedRole), + AddPendingRoleOnJoin: settings.GatekeepAddPendingRoleOnJoin, + ApprovedMessage: settings.GatekeepApprovedMessage, + ApprovedMessageV2: settings.GatekeepApprovedMessageV2, + ApprovedMessageV2Json: settings.GatekeepApprovedMessageV2Json, + }, nil +} + +// --- JoinLeaveSettings --- + +func (s *guildSettingsService) GetJoinLeaveSettings(ctx context.Context, req *heimdallrv1.GetJoinLeaveSettingsRequest) (*heimdallrv1.JoinLeaveSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.JoinLeaveSettings{ + GuildId: guildID.String(), + JoinMessageEnabled: settings.JoinMessageEnabled, + JoinMessage: settings.JoinMessage, + JoinMessageV2: settings.JoinMessageV2, + JoinMessageV2Json: settings.JoinMessageV2Json, + LeaveMessageEnabled: settings.LeaveMessageEnabled, + LeaveMessage: settings.LeaveMessage, + LeaveMessageV2: settings.LeaveMessageV2, + LeaveMessageV2Json: settings.LeaveMessageV2Json, + Channel: idStr(settings.JoinLeaveChannel), + }, nil +} + +func (s *guildSettingsService) UpdateJoinLeaveSettings(ctx context.Context, req *heimdallrv1.UpdateJoinLeaveSettingsRequest) (*heimdallrv1.JoinLeaveSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.JoinMessageEnabled = proto.GetJoinMessageEnabled() + settings.JoinMessage = proto.GetJoinMessage() + settings.JoinMessageV2 = proto.GetJoinMessageV2() + settings.JoinMessageV2Json = proto.GetJoinMessageV2Json() + settings.LeaveMessageEnabled = proto.GetLeaveMessageEnabled() + settings.LeaveMessage = proto.GetLeaveMessage() + settings.LeaveMessageV2 = proto.GetLeaveMessageV2() + settings.LeaveMessageV2Json = proto.GetLeaveMessageV2Json() + settings.JoinLeaveChannel = parseSnowflake(proto.GetChannel()) + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.JoinLeaveSettings{ + GuildId: guildID.String(), + JoinMessageEnabled: settings.JoinMessageEnabled, + JoinMessage: settings.JoinMessage, + JoinMessageV2: settings.JoinMessageV2, + JoinMessageV2Json: settings.JoinMessageV2Json, + LeaveMessageEnabled: settings.LeaveMessageEnabled, + LeaveMessage: settings.LeaveMessage, + LeaveMessageV2: settings.LeaveMessageV2, + LeaveMessageV2Json: settings.LeaveMessageV2Json, + Channel: idStr(settings.JoinLeaveChannel), + }, nil +} + +// --- AntiSpamSettings --- + +func (s *guildSettingsService) GetAntiSpamSettings(ctx context.Context, req *heimdallrv1.GetAntiSpamSettingsRequest) (*heimdallrv1.AntiSpamSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.AntiSpamSettings{ + GuildId: guildID.String(), + Enabled: settings.AntiSpamEnabled, + Count: int32(settings.AntiSpamCount), + CooldownSeconds: int32(settings.AntiSpamCooldownSeconds), + }, nil +} + +func (s *guildSettingsService) UpdateAntiSpamSettings(ctx context.Context, req *heimdallrv1.UpdateAntiSpamSettingsRequest) (*heimdallrv1.AntiSpamSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.AntiSpamEnabled = proto.GetEnabled() + settings.AntiSpamCount = int(proto.GetCount()) + settings.AntiSpamCooldownSeconds = int(proto.GetCooldownSeconds()) + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.AntiSpamSettings{ + GuildId: guildID.String(), + Enabled: settings.AntiSpamEnabled, + Count: int32(settings.AntiSpamCount), + CooldownSeconds: int32(settings.AntiSpamCooldownSeconds), + }, nil +} + +// --- BanFooterSettings --- + +func (s *guildSettingsService) GetBanFooterSettings(ctx context.Context, req *heimdallrv1.GetBanFooterSettingsRequest) (*heimdallrv1.BanFooterSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + return &heimdallrv1.BanFooterSettings{ + GuildId: guildID.String(), + Footer: settings.BanFooter, + AlwaysSend: settings.AlwaysSendBanFooter, + }, nil +} + +func (s *guildSettingsService) UpdateBanFooterSettings(ctx context.Context, req *heimdallrv1.UpdateBanFooterSettingsRequest) (*heimdallrv1.BanFooterSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + settings, err := model.GetGuildSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load settings")) + } + + settings.BanFooter = proto.GetFooter() + settings.AlwaysSendBanFooter = proto.GetAlwaysSend() + + if err := model.SetGuildSettings(settings); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save settings")) + } + + return &heimdallrv1.BanFooterSettings{ + GuildId: guildID.String(), + Footer: settings.BanFooter, + AlwaysSend: settings.AlwaysSendBanFooter, + }, nil +} + +// --- ModmailSettings --- + +func (s *guildSettingsService) GetModmailSettings(ctx context.Context, req *heimdallrv1.GetModmailSettingsRequest) (*heimdallrv1.ModmailSettings, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + ms, err := model.GetModmailSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load modmail settings")) + } + + return &heimdallrv1.ModmailSettings{ + GuildId: guildID.String(), + ReportThreadsChannel: idStr(ms.ReportThreadsChannel), + ReportNotificationChannel: idStr(ms.ReportNotificationChannel), + ReportPingRole: idStr(ms.ReportPingRole), + }, nil +} + +func (s *guildSettingsService) UpdateModmailSettings(ctx context.Context, req *heimdallrv1.UpdateModmailSettingsRequest) (*heimdallrv1.ModmailSettings, error) { + proto := req.GetSettings() + guildID, err := checkGuildAdmin(ctx, s.client, proto.GetGuildId()) + if err != nil { + return nil, err + } + + ms, err := model.GetModmailSettings(guildID) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to load modmail settings")) + } + + ms.ReportThreadsChannel = parseSnowflake(proto.GetReportThreadsChannel()) + ms.ReportNotificationChannel = parseSnowflake(proto.GetReportNotificationChannel()) + ms.ReportPingRole = parseSnowflake(proto.GetReportPingRole()) + + if err := model.SetModmailSettings(ms); err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to save modmail settings")) + } + + return &heimdallrv1.ModmailSettings{ + GuildId: guildID.String(), + ReportThreadsChannel: idStr(ms.ReportThreadsChannel), + ReportNotificationChannel: idStr(ms.ReportNotificationChannel), + ReportPingRole: idStr(ms.ReportPingRole), + }, nil +} + +// --- Guild Data (Channels & Roles) --- + +func (s *guildSettingsService) ListChannels(ctx context.Context, req *heimdallrv1.ListChannelsRequest) (*heimdallrv1.ListChannelsResponse, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + var channels []*heimdallrv1.Channel + for ch := range s.client.Caches.ChannelsForGuild(guildID) { + var parentID string + if pid := ch.ParentID(); pid != nil { + parentID = pid.String() + } + channels = append(channels, &heimdallrv1.Channel{ + Id: ch.ID().String(), + Name: ch.Name(), + Type: int32(ch.Type()), + Position: int32(ch.Position()), + ParentId: parentID, + }) + } + + return &heimdallrv1.ListChannelsResponse{Channels: channels}, nil +} + +func (s *guildSettingsService) ListRoles(ctx context.Context, req *heimdallrv1.ListRolesRequest) (*heimdallrv1.ListRolesResponse, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + var roles []*heimdallrv1.Role + for role := range s.client.Caches.Roles(guildID) { + roles = append(roles, &heimdallrv1.Role{ + Id: role.ID.String(), + Name: role.Name, + Color: int32(role.Color), + Position: int32(role.Position), + Managed: role.Managed, + }) + } + + return &heimdallrv1.ListRolesResponse{Roles: roles}, nil +} + +func (s *guildSettingsService) GetTemplatePlaceholders(ctx context.Context, _ *heimdallrv1.GetTemplatePlaceholdersRequest) (*heimdallrv1.GetTemplatePlaceholdersResponse, error) { + if SessionFromContext(ctx) == nil { + return nil, connect.NewError(connect.CodeUnauthenticated, nil) + } + + placeholders := make([]*heimdallrv1.TemplatePlaceholder, len(utils.MessageTemplatePlaceholders)) + for i, p := range utils.MessageTemplatePlaceholders { + placeholders[i] = &heimdallrv1.TemplatePlaceholder{ + Placeholder: p.Placeholder, + Description: p.Description, + } + } + return &heimdallrv1.GetTemplatePlaceholdersResponse{Placeholders: placeholders}, nil +} + +// buildEmojiMap builds a lowercase emoji name → Emoji lookup from the guild cache. +func (s *guildSettingsService) buildEmojiMap(guildID snowflake.ID) map[string]discord.Emoji { + emojiMap := make(map[string]discord.Emoji) + for emoji := range s.client.Caches.Emojis(guildID) { + emojiMap[strings.ToLower(emoji.Name)] = emoji + } + return emojiMap +} + +// --- SendComponentsMessage --- + +func (s *guildSettingsService) SendComponentsMessage(ctx context.Context, req *heimdallrv1.SendComponentsMessageRequest) (*heimdallrv1.SendComponentsMessageResponse, error) { + guildID, err := checkGuildAdmin(ctx, s.client, req.GetGuildId()) + if err != nil { + return nil, err + } + + channelID, err := snowflake.Parse(req.GetChannelId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid channel ID")) + } + + ch, ok := s.client.Caches.GuildMessageChannel(channelID) + if !ok || ch.GuildID() != guildID { + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("channel not found in this guild")) + } + + var parsed any + if err := json.Unmarshal([]byte(req.GetComponentsJson()), &parsed); err != nil { + slog.Error("invalid components JSON from client", "error", err) + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid components JSON")) + } + + utils.ResolveEmojis(parsed, s.buildEmojiMap(guildID)) + + resolvedJSON, err := json.Marshal(parsed) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to re-encode components")) + } + + components, err := utils.ParseComponents(string(resolvedJSON)) + if err != nil { + slog.Error("failed to parse resolved components", "error", err) + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid components JSON")) + } + + msg, err := s.client.Rest.CreateMessage(channelID, discord.MessageCreate{ + Flags: discord.MessageFlagIsComponentsV2, + Components: components, + }) + if err != nil { + slog.Error("failed to send Discord message", "error", err, "channel_id", channelID) + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to send message")) + } + + return &heimdallrv1.SendComponentsMessageResponse{ + MessageId: msg.ID.String(), + }, nil +} diff --git a/heimdallr/rpcserver/ratelimit.go b/heimdallr/rpcserver/ratelimit.go new file mode 100644 index 0000000..3fb52ae --- /dev/null +++ b/heimdallr/rpcserver/ratelimit.go @@ -0,0 +1,121 @@ +//go:build web + +package rpcserver + +import ( + "net" + "net/http" + "sync" + "time" + + "golang.org/x/time/rate" +) + +const ( + // exchangeCodeRatePerMinute is how many ExchangeCode requests a single IP + // can make per minute after the burst is exhausted. + exchangeCodeRatePerMinute = 1 + // exchangeCodeBurst is the number of ExchangeCode requests an IP can make + // in quick succession before the steady-state rate kicks in. + exchangeCodeBurst = 5 + // rateLimiterTTL is how long an IP entry is kept after its last request. + rateLimiterTTL = 10 * time.Minute + // maxRequestBodyBytes is the maximum allowed request body size across all + // endpoints. This guards against memory exhaustion from oversized payloads. + maxRequestBodyBytes int64 = 1 << 20 // 1 MiB +) + +type rateLimiterEntry struct { + limiter *rate.Limiter + lastSeen time.Time +} + +type ipRateLimiter struct { + mu sync.Mutex + limiters map[string]*rateLimiterEntry + limit rate.Limit + burst int +} + +func newIPRateLimiter(r rate.Limit, burst int) *ipRateLimiter { + return &ipRateLimiter{ + limiters: make(map[string]*rateLimiterEntry), + limit: r, + burst: burst, + } +} + +func (l *ipRateLimiter) getLimiter(ip string) *rate.Limiter { + l.mu.Lock() + defer l.mu.Unlock() + + entry, ok := l.limiters[ip] + if !ok { + entry = &rateLimiterEntry{limiter: rate.NewLimiter(l.limit, l.burst)} + l.limiters[ip] = entry + } + entry.lastSeen = time.Now() + return entry.limiter +} + +// cleanup removes IP entries that have not been seen within ttl. +func (l *ipRateLimiter) cleanup(ttl time.Duration) { + l.mu.Lock() + defer l.mu.Unlock() + + cutoff := time.Now().Add(-ttl) + for ip, entry := range l.limiters { + if entry.lastSeen.Before(cutoff) { + delete(l.limiters, ip) + } + } +} + +// clientIP extracts the client IP from the request. +// It trusts X-Real-IP (set by nginx/Caddy) when present, and falls back to +// RemoteAddr. Note: only deploy behind a trusted reverse proxy; otherwise +// X-Real-IP can be spoofed by clients. +func clientIP(r *http.Request) string { + if ip := r.Header.Get("X-Real-IP"); ip != "" { + return ip + } + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return r.RemoteAddr + } + return ip +} + +// newBodyLimitMiddleware returns an HTTP middleware that caps request bodies at +// maxRequestBodyBytes. Requests that exceed the limit receive 413. +func newBodyLimitMiddleware() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, maxRequestBodyBytes) + next.ServeHTTP(w, r) + }) + } +} + +// newRateLimitMiddleware returns an HTTP middleware that enforces per-IP rate +// limiting on the given URL paths. Requests to other paths are passed through +// unchanged. Requests that exceed the limit receive 429 Too Many Requests. +func newRateLimitMiddleware(rl *ipRateLimiter, paths ...string) func(http.Handler) http.Handler { + pathSet := make(map[string]bool, len(paths)) + for _, p := range paths { + pathSet[p] = true + } + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if pathSet[r.URL.Path] { + ip := clientIP(r) + if !rl.getLimiter(ip).Allow() { + http.Error(w, "rate limit exceeded", http.StatusTooManyRequests) + return + } + } + next.ServeHTTP(w, r) + }) + } +} diff --git a/heimdallr/rpcserver/rpcserver.go b/heimdallr/rpcserver/rpcserver.go new file mode 100644 index 0000000..3649ee1 --- /dev/null +++ b/heimdallr/rpcserver/rpcserver.go @@ -0,0 +1,117 @@ +//go:build web + +package rpcserver + +import ( + "fmt" + "log/slog" + "net/http" + "net/url" + "time" + + "connectrpc.com/connect" + "connectrpc.com/grpcreflect" + "connectrpc.com/validate" + "github.com/disgoorg/disgo/bot" + "github.com/rs/cors" + "github.com/spf13/viper" + "golang.org/x/time/rate" + + "github.com/NLLCommunity/heimdallr/gen/heimdallr/v1/heimdallrv1connect" + "github.com/NLLCommunity/heimdallr/model" +) + +func StartServer(addr string, discordClient *bot.Client) error { + baseURL := viper.GetString("dashboard.base_url") + devMode := viper.GetBool("dev_mode.enabled") + + // Validate dashboard.base_url. + parsedURL, err := url.Parse(baseURL) + if err != nil || parsedURL.Host == "" { + return fmt.Errorf("invalid dashboard.base_url %q: %w", baseURL, err) + } + if !devMode && parsedURL.Scheme == "http" { + slog.Warn("dashboard.base_url uses http — this is insecure in production", "url", baseURL) + } + + // Warn about missing TLS in production. + if !devMode { + slog.Warn("RPC server does not terminate TLS — use a reverse proxy (e.g. nginx, Caddy) with TLS in production") + } + + mux := http.NewServeMux() + + interceptors := connect.WithInterceptors( + newCookieInterceptor(), + validate.NewInterceptor(), + newAuthInterceptor(), + ) + + authSvc := &authService{client: discordClient} + authPath, authHandler := heimdallrv1connect.NewAuthServiceHandler(authSvc, interceptors) + mux.Handle(authPath, authHandler) + + settingsSvc := &guildSettingsService{client: discordClient} + settingsPath, settingsHandler := heimdallrv1connect.NewGuildSettingsServiceHandler(settingsSvc, interceptors) + mux.Handle(settingsPath, settingsHandler) + + // Only expose gRPC reflection in dev mode. + if devMode { + reflector := grpcreflect.NewStaticReflector( + heimdallrv1connect.AuthServiceName, + heimdallrv1connect.GuildSettingsServiceName, + ) + mux.Handle(grpcreflect.NewHandlerV1(reflector)) + mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) + } + + // Serve embedded frontend as SPA fallback (catch-all for non-RPC paths). + mux.Handle("/", newSPAHandler()) + + // Clean expired sessions and stale rate-limiter entries periodically. + exchangeCodeLimiter := newIPRateLimiter( + rate.Every(time.Minute/exchangeCodeRatePerMinute), + exchangeCodeBurst, + ) + go func() { + ticker := time.NewTicker(15 * time.Minute) + defer ticker.Stop() + for range ticker.C { + model.CleanExpiredSessions() + exchangeCodeLimiter.cleanup(rateLimiterTTL) + } + }() + + // Build the middleware chain (innermost to outermost): + // mux → body limit → rate limit → CORS + // CORS is outermost so OPTIONS preflight requests are handled before the + // body limit or rate limiter run. + withBodyLimit := newBodyLimitMiddleware()(mux) + withRateLimit := newRateLimitMiddleware( + exchangeCodeLimiter, + heimdallrv1connect.AuthServiceExchangeCodeProcedure, + )(withBodyLimit) + corsHandler := cors.New(cors.Options{ + AllowedOrigins: []string{baseURL}, + AllowedMethods: []string{"POST", "GET", "OPTIONS"}, + AllowedHeaders: []string{"Authorization", "Content-Type", "Connect-Protocol-Version"}, + AllowCredentials: true, + }).Handler(withRateLimit) + + p := new(http.Protocols) + p.SetHTTP1(true) + p.SetUnencryptedHTTP2(true) + + s := http.Server{ + Addr: addr, + Handler: corsHandler, + Protocols: p, + ReadHeaderTimeout: 5 * time.Second, + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + IdleTimeout: 120 * time.Second, + } + + slog.Info("Starting RPC server on address: " + addr) + return s.ListenAndServe() +} diff --git a/heimdallr/rpcserver/rpcserver_dummy.go b/heimdallr/rpcserver/rpcserver_dummy.go new file mode 100644 index 0000000..2a378af --- /dev/null +++ b/heimdallr/rpcserver/rpcserver_dummy.go @@ -0,0 +1,14 @@ +//go:build !web + +package rpcserver + +import ( + "log/slog" + + "github.com/disgoorg/disgo/bot" +) + +func StartServer(addr string, client *bot.Client) error { + slog.Info("RPC Server and Web not available") + return nil +} diff --git a/scheduled_tasks/remove_pending_prunes.go b/heimdallr/scheduled_tasks/remove_pending_prunes.go similarity index 100% rename from scheduled_tasks/remove_pending_prunes.go rename to heimdallr/scheduled_tasks/remove_pending_prunes.go diff --git a/scheduled_tasks/remove_temp_bans.go b/heimdallr/scheduled_tasks/remove_temp_bans.go similarity index 100% rename from scheduled_tasks/remove_temp_bans.go rename to heimdallr/scheduled_tasks/remove_temp_bans.go diff --git a/scheduled_tasks/scheduled_tasks_test.go b/heimdallr/scheduled_tasks/scheduled_tasks_test.go similarity index 100% rename from scheduled_tasks/scheduled_tasks_test.go rename to heimdallr/scheduled_tasks/scheduled_tasks_test.go diff --git a/task/task.go b/heimdallr/task/task.go similarity index 100% rename from task/task.go rename to heimdallr/task/task.go diff --git a/task/task_test.go b/heimdallr/task/task_test.go similarity index 100% rename from task/task_test.go rename to heimdallr/task/task_test.go diff --git a/heimdallr/utils/components.go b/heimdallr/utils/components.go new file mode 100644 index 0000000..4f6055b --- /dev/null +++ b/heimdallr/utils/components.go @@ -0,0 +1,177 @@ +package utils + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/cbroglie/mustache" + "github.com/disgoorg/disgo/discord" +) + +// ResolveEmojis walks a JSON value tree looking for "emoji" keys whose value +// is an object with "name" but no "id", and resolves the name against the +// provided emoji map. +func ResolveEmojis(v any, emojiMap map[string]discord.Emoji) { + switch val := v.(type) { + case map[string]any: + if emojiObj, ok := val["emoji"].(map[string]any); ok { + if name, ok := emojiObj["name"].(string); ok { + _, hasID := emojiObj["id"] + if !hasID || emojiObj["id"] == nil { + cleaned := strings.Trim(name, ":") + if emoji, found := emojiMap[strings.ToLower(cleaned)]; found { + emojiObj["name"] = emoji.Name + emojiObj["id"] = emoji.ID.String() + } + } + } + } + for _, child := range val { + ResolveEmojis(child, emojiMap) + } + case []any: + for _, item := range val { + ResolveEmojis(item, emojiMap) + } + } +} + +// RenderComponentTemplates applies mustache template rendering to all string +// values in the "content" fields of a parsed component JSON tree. +func RenderComponentTemplates(componentsJson string, data MessageTemplateData) (string, error) { + var parsed any + if err := json.Unmarshal([]byte(componentsJson), &parsed); err != nil { + return "", err + } + + if err := renderTemplatesInTree(parsed, data); err != nil { + return "", err + } + + result, err := json.Marshal(parsed) + if err != nil { + return "", err + } + return string(result), nil +} + +func renderTemplatesInTree(v any, data MessageTemplateData) error { + switch val := v.(type) { + case map[string]any: + if content, ok := val["content"].(string); ok { + rendered, err := mustache.RenderRaw(content, true, data) + if err != nil { + return err + } + val["content"] = rendered + } + for _, child := range val { + if err := renderTemplatesInTree(child, data); err != nil { + return err + } + } + case []any: + for _, item := range val { + if err := renderTemplatesInTree(item, data); err != nil { + return err + } + } + } + return nil +} + +// BuildV2Message renders mustache templates in the component JSON, resolves +// emoji names, and parses the result into layout components ready for sending. +func BuildV2Message(componentsJson string, data MessageTemplateData, emojiMap map[string]discord.Emoji) ([]discord.LayoutComponent, error) { + rendered, err := RenderComponentTemplates(componentsJson, data) + if err != nil { + return nil, err + } + + var parsed any + if err := json.Unmarshal([]byte(rendered), &parsed); err != nil { + return nil, err + } + ResolveEmojis(parsed, emojiMap) + + resolvedJSON, err := json.Marshal(parsed) + if err != nil { + return nil, err + } + + return ParseComponents(string(resolvedJSON)) +} + +// flattenSections pre-processes the JSON component tree. Sections without an +// accessory are invalid (Discord requires one), so they are flattened into +// their child text_display components. This also prevents a panic in disgo's +// SectionComponent.UnmarshalJSON which assumes a non-nil accessory. +func flattenSections(items []any) []any { + result := make([]any, 0, len(items)) + for _, item := range items { + obj, ok := item.(map[string]any) + if !ok { + result = append(result, item) + continue + } + + typeNum, _ := obj["type"].(float64) + + // Recurse into containers + if int(typeNum) == int(discord.ComponentTypeContainer) { + if children, ok := obj["components"].([]any); ok { + obj["components"] = flattenSections(children) + } + } + + // Section without accessory → promote children to text_display + if int(typeNum) == int(discord.ComponentTypeSection) { + if _, hasAccessory := obj["accessory"]; !hasAccessory { + if children, ok := obj["components"].([]any); ok { + result = append(result, children...) + } + continue + } + } + + result = append(result, obj) + } + return result +} + +// ParseComponents unmarshals a JSON string into Discord layout components. +// Sections without an accessory are flattened into text displays to satisfy +// both Discord's API requirements and disgo's unmarshaler. +func ParseComponents(jsonStr string) (components []discord.LayoutComponent, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("failed to parse components: %v", r) + } + }() + + var parsed []any + if err := json.Unmarshal([]byte(jsonStr), &parsed); err != nil { + return nil, err + } + + patched, err := json.Marshal(flattenSections(parsed)) + if err != nil { + return nil, err + } + + var raw []discord.UnmarshalComponent + if err := json.Unmarshal(patched, &raw); err != nil { + return nil, err + } + + components = make([]discord.LayoutComponent, 0, len(raw)) + for _, r := range raw { + lc, ok := r.Component.(discord.LayoutComponent) + if !ok { + continue + } + components = append(components, lc) + } + return components, nil +} diff --git a/utils/discord_time.go b/heimdallr/utils/discord_time.go similarity index 100% rename from utils/discord_time.go rename to heimdallr/utils/discord_time.go diff --git a/utils/discord_time_test.go b/heimdallr/utils/discord_time_test.go similarity index 100% rename from utils/discord_time_test.go rename to heimdallr/utils/discord_time_test.go diff --git a/utils/interaction_log.go b/heimdallr/utils/interaction_log.go similarity index 100% rename from utils/interaction_log.go rename to heimdallr/utils/interaction_log.go diff --git a/utils/mentions.go b/heimdallr/utils/mentions.go similarity index 100% rename from utils/mentions.go rename to heimdallr/utils/mentions.go diff --git a/utils/mentions_test.go b/heimdallr/utils/mentions_test.go similarity index 100% rename from utils/mentions_test.go rename to heimdallr/utils/mentions_test.go diff --git a/heimdallr/utils/template_data.go b/heimdallr/utils/template_data.go new file mode 100644 index 0000000..dcc35e7 --- /dev/null +++ b/heimdallr/utils/template_data.go @@ -0,0 +1,79 @@ +package utils + +import ( + "fmt" + "strings" + + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" +) + +type MessageTemplateData struct { + User TemplateUserData + Server TemplateGuildData +} + +type TemplateUserData struct { + Username string + GlobalName string + ServerName string + ResolvedName string + Mention string + Discriminator uint8 + IsBot bool + ID snowflake.ID +} + +type TemplateGuildData struct { + Name string + ID snowflake.ID +} + +func NewMessageTemplateData(user discord.Member, guild discord.Guild) MessageTemplateData { + return MessageTemplateData{ + User: TemplateUserData{ + Username: Iif( + user.User.Discriminator == "0", + user.User.Username, + user.User.Username+"#"+user.User.Discriminator, + ), + GlobalName: RefDefault(user.User.GlobalName, ""), + ServerName: RefDefault(user.Nick, ""), + ResolvedName: user.EffectiveName(), + Mention: user.Mention(), + ID: user.User.ID, + }, + Server: TemplateGuildData{ + Name: guild.Name, + ID: guild.ID, + }, + } +} + +// MessageTemplatePlaceholder describes a single template placeholder. +type MessageTemplatePlaceholder struct { + Placeholder string + Description string +} + +// MessageTemplatePlaceholders is the structured list of available placeholders. +var MessageTemplatePlaceholders = []MessageTemplatePlaceholder{ + {"{{User.Username}}", `Username (e.g. "Username#1234" or "username")`}, + {"{{User.GlobalName}}", "The user's global display name"}, + {"{{User.ServerName}}", "The user's server nickname, if any"}, + {"{{User.ResolvedName}}", "Server nickname, global name, or username (first available)"}, + {"{{User.Mention}}", "Mentions the user"}, + {"{{User.ID}}", "The user's ID"}, + {"{{Server.Name}}", "The server name"}, + {"{{Server.ID}}", "The server ID"}, +} + +var MessageTemplateInfo = func() string { + var b strings.Builder + b.WriteString("The following placeholders can be used in join/leave/approval messages " + + "and will be replaced with the appropriate values.\n\n") + for _, p := range MessageTemplatePlaceholders { + fmt.Fprintf(&b, "`%s` — %s\n", p.Placeholder, p.Description) + } + return b.String() +}() diff --git a/utils/users.go b/heimdallr/utils/users.go similarity index 100% rename from utils/users.go rename to heimdallr/utils/users.go diff --git a/utils/users_test.go b/heimdallr/utils/users_test.go similarity index 100% rename from utils/users_test.go rename to heimdallr/utils/users_test.go diff --git a/utils/utils.go b/heimdallr/utils/utils.go similarity index 98% rename from utils/utils.go rename to heimdallr/utils/utils.go index 9882f27..eeecadd 100644 --- a/utils/utils.go +++ b/heimdallr/utils/utils.go @@ -127,11 +127,14 @@ func GetMembersIter(r rest.Rest, guildID snowflake.ID) iter.Seq[IterResult[disco for { members, err := r.GetMembers(guildID, LIMIT, memberOffset) if err != nil { - yield( + cont := yield( IterResult[discord.Member]{ Error: err, }, ) + if !cont { + break + } } count := len(members) diff --git a/utils/utils_test.go b/heimdallr/utils/utils_test.go similarity index 100% rename from utils/utils_test.go rename to heimdallr/utils/utils_test.go diff --git a/listeners/joinleave.go b/listeners/joinleave.go deleted file mode 100644 index 381db40..0000000 --- a/listeners/joinleave.go +++ /dev/null @@ -1,115 +0,0 @@ -package listeners - -import ( - "log/slog" - - "github.com/cbroglie/mustache" - "github.com/disgoorg/disgo/discord" - "github.com/disgoorg/disgo/events" - - "github.com/NLLCommunity/heimdallr/model" - "github.com/NLLCommunity/heimdallr/utils" -) - -func OnUserJoin(e *events.GuildMemberJoin) { - guildID := e.GuildID - guild, err := e.Client().Rest.GetGuild(guildID, false) - if err != nil { - return - } - - guildSettings, err := model.GetGuildSettings(guildID) - if err != nil { - return - } - - if !guildSettings.JoinMessageEnabled { - return - } - - joinLeaveChannel := guildSettings.JoinLeaveChannel - if joinLeaveChannel == 0 && guild.SystemChannelID != nil { - joinLeaveChannel = *guild.SystemChannelID - } - if joinLeaveChannel == 0 { - return - } - - joinleaveInfo := utils.NewMessageTemplateData(e.Member, guild.Guild) - - contents, err := mustache.RenderRaw(guildSettings.JoinMessage, true, joinleaveInfo) - if err != nil { - slog.Error( - "Failed to render join message template.", - "err", err, - "guild_id", guildID, - ) - return - } - - _, err = e.Client().Rest.CreateMessage( - joinLeaveChannel, discord.NewMessageCreate().WithContent(contents), - ) - if err != nil { - slog.Error( - "Failed to send join message.", - "guild_id", guildID, - "channel_id", joinLeaveChannel, - "err", err, - ) - } -} - -func OnUserLeave(e *events.GuildMemberLeave) { - guildID := e.GuildID - guild, err := e.Client().Rest.GetGuild(guildID, false) - if err != nil { - return - } - - guildSettings, err := model.GetGuildSettings(guildID) - if err != nil { - return - } - - if !guildSettings.LeaveMessageEnabled { - return - } - - joinLeaveChannel := guildSettings.JoinLeaveChannel - if joinLeaveChannel == 0 && guild.SystemChannelID != nil { - joinLeaveChannel = *guild.SystemChannelID - } - if joinLeaveChannel == 0 { - return - } - - if pruned, _ := model.IsMemberPruned(guildID, e.User.ID); pruned { - return - } - - e.Member.User = e.User - joinleaveInfo := utils.NewMessageTemplateData(e.Member, guild.Guild) - - contents, err := mustache.RenderRaw(guildSettings.LeaveMessage, true, joinleaveInfo) - if err != nil { - slog.Error( - "Failed to render leave message template.", - "err", err, - "guild_id", guildID, - ) - return - } - - _, err = e.Client().Rest.CreateMessage( - joinLeaveChannel, discord.NewMessageCreate().WithContent(contents), - ) - if err != nil { - slog.Error( - "Failed to send leave message.", - "guild_id", guildID, - "channel_id", joinLeaveChannel, - "err", err, - ) - } -} diff --git a/start.sh b/start.sh index d8a6754..0decba2 100755 --- a/start.sh +++ b/start.sh @@ -16,6 +16,7 @@ echo "DB_REPLICA_URL=${DB_REPLICA_URL:-}" readonly DB_PATH="${HEIMDALLR_BOT_DB:-heimdallr.db}" export DB_PATH +export HEIMDALLR_WEB_ADDRESS=":${PORT:-8484}" if [ -f "$DB_PATH" ]; then echo "Existing database is $(stat -c %s "${DB_PATH}") bytes" diff --git a/utils/template_data.go b/utils/template_data.go deleted file mode 100644 index 74c8f56..0000000 --- a/utils/template_data.go +++ /dev/null @@ -1,62 +0,0 @@ -package utils - -import ( - "github.com/disgoorg/disgo/discord" - "github.com/disgoorg/snowflake/v2" -) - -type MessageTemplateData struct { - User TemplateUserData - Server TemplateGuildData -} - -type TemplateUserData struct { - Username string - GlobalName string - ServerName string - ResolvedName string - Mention string - Discriminator uint8 - IsBot bool - ID snowflake.ID -} - -type TemplateGuildData struct { - Name string - ID snowflake.ID -} - -func NewMessageTemplateData(user discord.Member, guild discord.Guild) MessageTemplateData { - return MessageTemplateData{ - User: TemplateUserData{ - Username: Iif( - user.User.Discriminator == "0", - user.User.Username, - user.User.Username+"#"+user.User.Discriminator, - ), - GlobalName: RefDefault(user.User.GlobalName, ""), - ServerName: RefDefault(user.Nick, ""), - ResolvedName: user.EffectiveName(), - Mention: user.Mention(), - ID: user.User.ID, - }, - Server: TemplateGuildData{ - Name: guild.Name, - ID: guild.ID, - }, - } -} - -var MessageTemplateInfo = "The following placeholders can be used in join/leave/approval messages " + - "and will be replaced with the appropriate values." + - "\n" + - "\n" + - "**Username:** `{{User.Username}}` will show as \"Username#1234\" or \"username\"\n" + - "**Global name:** `{{User.GlobalName}}` will show the user's global display name\n" + - "**Server name:** `{{User.ServerName}}` will show the user's server nickname, if any\n" + - "**Resolved name:** `{{User.ResolvedName}}` will show the user's resolved name, which is" + - "the server nickname if set, otherwise the global name, or username if neither is set\n" + - "**Mention:** `{{User.Mention}}` will mention the user if it is used\n" + - "**User ID:** `{{User.ID}}` will show the user's ID\n" + - "**Server name:** `{{Server.Name}}` will show the server name\n" + - "**Server ID:** `{{Server.ID}}` will show the server ID\n" diff --git a/web-dashboard/.gitignore b/web-dashboard/.gitignore new file mode 100644 index 0000000..0030910 --- /dev/null +++ b/web-dashboard/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + + +node_modules diff --git a/web-dashboard/.vscode/extensions.json b/web-dashboard/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/web-dashboard/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/web-dashboard/README.md b/web-dashboard/README.md new file mode 100644 index 0000000..e6cd94f --- /dev/null +++ b/web-dashboard/README.md @@ -0,0 +1,47 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/web-dashboard/bun.lock b/web-dashboard/bun.lock new file mode 100644 index 0000000..ab4650c --- /dev/null +++ b/web-dashboard/bun.lock @@ -0,0 +1,309 @@ +{ + "lockfileVersion": 1, + "configVersion": 0, + "workspaces": { + "": { + "name": "web-dashboard", + "dependencies": { + "@connectrpc/connect": "^2.1.1", + "@connectrpc/connect-web": "^2.1.1", + "@tailwindcss/vite": "^4.1.18", + "daisyui": "^5.5.18", + "svelte-spa-router": "^4.0.1", + "tailwindcss": "^4.1.18", + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tsconfig/svelte": "^5.0.6", + "@types/node": "^24.10.1", + "svelte": "^5.45.2", + "svelte-check": "^4.3.4", + "typescript": "~5.9.3", + "vite": "^7.3.1", + }, + }, + }, + "packages": { + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], + + "@connectrpc/connect": ["@connectrpc/connect@2.1.1", "", { "peerDependencies": { "@bufbuild/protobuf": "^2.7.0" } }, "sha512-JzhkaTvM73m2K1URT6tv53k2RwngSmCXLZJgK580qNQOXRzZRR/BCMfZw3h+90JpnG6XksP5bYT+cz0rpUzUWQ=="], + + "@connectrpc/connect-web": ["@connectrpc/connect-web@2.1.1", "", { "peerDependencies": { "@bufbuild/protobuf": "^2.7.0", "@connectrpc/connect": "2.1.1" } }, "sha512-J8317Q2MaFRCT1jzVR1o06bZhDIBmU0UAzWx6xOIXzOq8+k71/+k7MUF7AwcBUX+34WIvbm5syRgC5HXQA8fOg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="], + + "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.9", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA=="], + + "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.2.4", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "deepmerge": "^4.3.1", "magic-string": "^0.30.21", "obug": "^2.1.0", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA=="], + + "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.2", "", { "dependencies": { "obug": "^2.1.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig=="], + + "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="], + + "@tailwindcss/vite": ["@tailwindcss/vite@4.1.18", "", { "dependencies": { "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "tailwindcss": "4.1.18" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA=="], + + "@tsconfig/svelte": ["@tsconfig/svelte@5.0.7", "", {}, "sha512-NOtJF9LQnV7k6bpzcXwL/rXdlFHvAT9e0imrftiMc6/+FUNBHRZ8UngDrM+jciA6ENzFYNoFs8rfwumuGF+Dhw=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/node": ["@types/node@24.10.13", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg=="], + + "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "daisyui": ["daisyui@5.5.18", "", {}, "sha512-VVzjpOitMGB6DWIBeRSapbjdOevFqyzpk9u5Um6a4tyId3JFrU5pbtF0vgjXDth76mJZbueN/j9Ok03SPrh/og=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "devalue": ["devalue@5.6.2", "", {}, "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg=="], + + "enhanced-resolve": ["enhanced-resolve@5.19.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg=="], + + "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + + "esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="], + + "esrap": ["esrap@2.2.3", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], + + "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "regexparam": ["regexparam@2.0.2", "", {}, "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w=="], + + "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], + + "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "svelte": ["svelte@5.51.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.2", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-AqApqNOxVS97V4Ko9UHTHeSuDJrwauJhZpLDs1gYD8Jk48ntCSWD7NxKje+fnGn5Ja1O3u2FzQZHPdifQjXe3w=="], + + "svelte-check": ["svelte-check@4.4.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-gB3FdEPb8tPO3Y7Dzc6d/Pm/KrXAhK+0Fk+LkcysVtupvAh6Y/IrBCEZNupq57oh0hcwlxCUamu/rq7GtvfSEg=="], + + "svelte-spa-router": ["svelte-spa-router@4.0.1", "", { "dependencies": { "regexparam": "2.0.2" } }, "sha512-2JkmUQ2f9jRluijL58LtdQBIpynSbem2eBGp4zXdi7aDY1znbR6yjw0KsonD0aq2QLwf4Yx4tBJQjxIjgjXHKg=="], + + "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="], + + "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], + + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + + "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], + + "zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], + + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + + "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + } +} diff --git a/web-dashboard/index.html b/web-dashboard/index.html new file mode 100644 index 0000000..9ddfa97 --- /dev/null +++ b/web-dashboard/index.html @@ -0,0 +1,12 @@ + + + + + + Heimdallr Dashboard + + +
    + + + diff --git a/web-dashboard/package.json b/web-dashboard/package.json new file mode 100644 index 0000000..f6ef29d --- /dev/null +++ b/web-dashboard/package.json @@ -0,0 +1,29 @@ +{ + "name": "web-dashboard", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tsconfig/svelte": "^5.0.6", + "@types/node": "^24.10.1", + "svelte": "^5.45.2", + "svelte-check": "^4.3.4", + "typescript": "~5.9.3", + "vite": "^7.3.1" + }, + "dependencies": { + "@connectrpc/connect": "^2.1.1", + "@connectrpc/connect-web": "^2.1.1", + "@tailwindcss/vite": "^4.1.18", + "daisyui": "^5.5.18", + "svelte-spa-router": "^4.0.1", + "tailwindcss": "^4.1.18" + } +} diff --git a/web-dashboard/src/App.svelte b/web-dashboard/src/App.svelte new file mode 100644 index 0000000..17e6363 --- /dev/null +++ b/web-dashboard/src/App.svelte @@ -0,0 +1,18 @@ + + + diff --git a/web-dashboard/src/app.css b/web-dashboard/src/app.css new file mode 100644 index 0000000..4c1b0c2 --- /dev/null +++ b/web-dashboard/src/app.css @@ -0,0 +1,2 @@ +@import "tailwindcss"; +@plugin "daisyui"; diff --git a/web-dashboard/src/gen/buf/validate/validate_pb.ts b/web-dashboard/src/gen/buf/validate/validate_pb.ts new file mode 100644 index 0000000..ff83229 --- /dev/null +++ b/web-dashboard/src/gen/buf/validate/validate_pb.ts @@ -0,0 +1,4967 @@ +// Copyright 2023-2026 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated from file buf/validate/validate.proto (package buf.validate, syntax proto2) +/* eslint-disable */ + +// [Protovalidate](https://protovalidate.com/) is the semantic validation library for Protobuf. +// It provides standard annotations to validate common rules on messages and fields, as well as the ability to use [CEL](https://cel.dev) to write custom rules. +// It's the next generation of [protoc-gen-validate](https://github.com/bufbuild/protoc-gen-validate). +// +// This package provides the options, messages, and enums that power Protovalidate. +// Apply its options to messages, fields, and oneofs in your Protobuf schemas to add validation rules: +// +// ```proto +// message User { +// string id = 1 [(buf.validate.field).string.uuid = true]; +// string first_name = 2 [(buf.validate.field).string.max_len = 64]; +// string last_name = 3 [(buf.validate.field).string.max_len = 64]; +// +// option (buf.validate.message).cel = { +// id: "first_name_requires_last_name" +// message: "last_name must be present if first_name is present" +// expression: "!has(this.first_name) || has(this.last_name)" +// }; +// } +// ``` +// +// These rules are enforced at runtime by language-specific libraries. +// See the [developer quickstart](https://protovalidate.com/quickstart/) to get started, or go directly to the runtime library for your language: +// [Go](https://github.com/bufbuild/protovalidate-go) +// [JavaScript/TypeScript](https://github.com/bufbuild/protovalidate-es), +// [Java](https://github.com/bufbuild/protovalidate-java), +// [Python](https://github.com/bufbuild/protovalidate-python), +// or [C++](https://github.com/bufbuild/protovalidate-cc). + +import type { GenEnum, GenExtension, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { enumDesc, extDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Duration, FieldDescriptorProto_Type, FieldMask, FieldOptions, MessageOptions, OneofOptions, Timestamp } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_field_mask, file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file buf/validate/validate.proto. + */ +export const file_buf_validate_validate: GenFile = /*@__PURE__*/ + fileDesc("ChtidWYvdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8SDGJ1Zi52YWxpZGF0ZSI3CgRSdWxlEgoKAmlkGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEgoKZXhwcmVzc2lvbhgDIAEoCSKGAQoMTWVzc2FnZVJ1bGVzEhYKDmNlbF9leHByZXNzaW9uGAUgAygJEh8KA2NlbBgDIAMoCzISLmJ1Zi52YWxpZGF0ZS5SdWxlEi0KBW9uZW9mGAQgAygLMh4uYnVmLnZhbGlkYXRlLk1lc3NhZ2VPbmVvZlJ1bGVKBAgBEAJSCGRpc2FibGVkIjQKEE1lc3NhZ2VPbmVvZlJ1bGUSDgoGZmllbGRzGAEgAygJEhAKCHJlcXVpcmVkGAIgASgIIh4KCk9uZW9mUnVsZXMSEAoIcmVxdWlyZWQYASABKAgiiwkKCkZpZWxkUnVsZXMSFgoOY2VsX2V4cHJlc3Npb24YHSADKAkSHwoDY2VsGBcgAygLMhIuYnVmLnZhbGlkYXRlLlJ1bGUSEAoIcmVxdWlyZWQYGSABKAgSJAoGaWdub3JlGBsgASgOMhQuYnVmLnZhbGlkYXRlLklnbm9yZRIpCgVmbG9hdBgBIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GbG9hdFJ1bGVzSAASKwoGZG91YmxlGAIgASgLMhkuYnVmLnZhbGlkYXRlLkRvdWJsZVJ1bGVzSAASKQoFaW50MzIYAyABKAsyGC5idWYudmFsaWRhdGUuSW50MzJSdWxlc0gAEikKBWludDY0GAQgASgLMhguYnVmLnZhbGlkYXRlLkludDY0UnVsZXNIABIrCgZ1aW50MzIYBSABKAsyGS5idWYudmFsaWRhdGUuVUludDMyUnVsZXNIABIrCgZ1aW50NjQYBiABKAsyGS5idWYudmFsaWRhdGUuVUludDY0UnVsZXNIABIrCgZzaW50MzIYByABKAsyGS5idWYudmFsaWRhdGUuU0ludDMyUnVsZXNIABIrCgZzaW50NjQYCCABKAsyGS5idWYudmFsaWRhdGUuU0ludDY0UnVsZXNIABItCgdmaXhlZDMyGAkgASgLMhouYnVmLnZhbGlkYXRlLkZpeGVkMzJSdWxlc0gAEi0KB2ZpeGVkNjQYCiABKAsyGi5idWYudmFsaWRhdGUuRml4ZWQ2NFJ1bGVzSAASLwoIc2ZpeGVkMzIYCyABKAsyGy5idWYudmFsaWRhdGUuU0ZpeGVkMzJSdWxlc0gAEi8KCHNmaXhlZDY0GAwgASgLMhsuYnVmLnZhbGlkYXRlLlNGaXhlZDY0UnVsZXNIABInCgRib29sGA0gASgLMhcuYnVmLnZhbGlkYXRlLkJvb2xSdWxlc0gAEisKBnN0cmluZxgOIAEoCzIZLmJ1Zi52YWxpZGF0ZS5TdHJpbmdSdWxlc0gAEikKBWJ5dGVzGA8gASgLMhguYnVmLnZhbGlkYXRlLkJ5dGVzUnVsZXNIABInCgRlbnVtGBAgASgLMhcuYnVmLnZhbGlkYXRlLkVudW1SdWxlc0gAEi8KCHJlcGVhdGVkGBIgASgLMhsuYnVmLnZhbGlkYXRlLlJlcGVhdGVkUnVsZXNIABIlCgNtYXAYEyABKAsyFi5idWYudmFsaWRhdGUuTWFwUnVsZXNIABIlCgNhbnkYFCABKAsyFi5idWYudmFsaWRhdGUuQW55UnVsZXNIABIvCghkdXJhdGlvbhgVIAEoCzIbLmJ1Zi52YWxpZGF0ZS5EdXJhdGlvblJ1bGVzSAASMgoKZmllbGRfbWFzaxgcIAEoCzIcLmJ1Zi52YWxpZGF0ZS5GaWVsZE1hc2tSdWxlc0gAEjEKCXRpbWVzdGFtcBgWIAEoCzIcLmJ1Zi52YWxpZGF0ZS5UaW1lc3RhbXBSdWxlc0gAQgYKBHR5cGVKBAgYEBlKBAgaEBtSB3NraXBwZWRSDGlnbm9yZV9lbXB0eSJVCg9QcmVkZWZpbmVkUnVsZXMSHwoDY2VsGAEgAygLMhIuYnVmLnZhbGlkYXRlLlJ1bGVKBAgYEBlKBAgaEBtSB3NraXBwZWRSDGlnbm9yZV9lbXB0eSLaFwoKRmxvYXRSdWxlcxKDAQoFY29uc3QYASABKAJCdMJIcQpvCgtmbG9hdC5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEp8BCgJsdBgCIAEoAkKQAcJIjAEKiQEKCGZsb2F0Lmx0Gn0haGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0KT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEq8BCgNsdGUYAyABKAJCnwHCSJsBCpgBCglmbG9hdC5sdGUaigEhaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID4gcnVsZXMubHRlKT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABLvBwoCZ3QYBCABKAJC4AfCSNwHCo0BCghmbG9hdC5ndBqAASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCsMBCgtmbG9hdC5ndF9sdBqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCs0BChVmbG9hdC5ndF9sdF9leGNsdXNpdmUaswFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrTAQoMZmxvYXQuZ3RfbHRlGsIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycK3QEKFmZsb2F0Lmd0X2x0ZV9leGNsdXNpdmUawgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEroICgNndGUYBSABKAJCqgjCSKYICpsBCglmbG9hdC5ndGUajQEhaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgKHRoaXMuaXNOYW4oKSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycK0gEKDGZsb2F0Lmd0ZV9sdBrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK3AEKFmZsb2F0Lmd0ZV9sdF9leGNsdXNpdmUawQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSkpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCuIBCg1mbG9hdC5ndGVfbHRlGtABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrsAQoXZmxvYXQuZ3RlX2x0ZV9leGNsdXNpdmUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESfwoCaW4YBiADKAJCc8JIcApuCghmbG9hdC5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSdgoGbm90X2luGAcgAygCQmbCSGMKYQoMZmxvYXQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSdQoGZmluaXRlGAggASgIQmXCSGIKYAoMZmxvYXQuZmluaXRlGlBydWxlcy5maW5pdGUgPyAodGhpcy5pc05hbigpIHx8IHRoaXMuaXNJbmYoKSA/ICd2YWx1ZSBtdXN0IGJlIGZpbml0ZScgOiAnJykgOiAnJxIrCgdleGFtcGxlGAkgAygCQhrCSBcKFQoNZmxvYXQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i7RcKC0RvdWJsZVJ1bGVzEoQBCgVjb25zdBgBIAEoAUJ1wkhyCnAKDGRvdWJsZS5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEqABCgJsdBgCIAEoAUKRAcJIjQEKigEKCWRvdWJsZS5sdBp9IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+PSBydWxlcy5sdCk/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKwAQoDbHRlGAMgASgBQqABwkicAQqZAQoKZG91YmxlLmx0ZRqKASFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPiBydWxlcy5sdGUpPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEvQHCgJndBgEIAEoAULlB8JI4QcKjgEKCWRvdWJsZS5ndBqAASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCsQBCgxkb3VibGUuZ3RfbHQaswFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrOAQoWZG91YmxlLmd0X2x0X2V4Y2x1c2l2ZRqzAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCtQBCg1kb3VibGUuZ3RfbHRlGsIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycK3gEKF2RvdWJsZS5ndF9sdGVfZXhjbHVzaXZlGsIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARK/CAoDZ3RlGAUgASgBQq8IwkirCAqcAQoKZG91YmxlLmd0ZRqNASFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiAodGhpcy5pc05hbigpIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrTAQoNZG91YmxlLmd0ZV9sdBrBAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK3QEKF2RvdWJsZS5ndGVfbHRfZXhjbHVzaXZlGsEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAodGhpcy5pc05hbigpIHx8IChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrjAQoOZG91YmxlLmd0ZV9sdGUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzLmlzTmFuKCkgfHwgdGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCu0BChhkb3VibGUuZ3RlX2x0ZV9leGNsdXNpdmUa0AFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHRoaXMuaXNOYW4oKSB8fCAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgAEKAmluGAYgAygBQnTCSHEKbwoJZG91YmxlLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YByADKAFCZ8JIZApiCg1kb3VibGUubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSdgoGZmluaXRlGAggASgIQmbCSGMKYQoNZG91YmxlLmZpbml0ZRpQcnVsZXMuZmluaXRlID8gKHRoaXMuaXNOYW4oKSB8fCB0aGlzLmlzSW5mKCkgPyAndmFsdWUgbXVzdCBiZSBmaW5pdGUnIDogJycpIDogJycSLAoHZXhhbXBsZRgJIAMoAUIbwkgYChYKDmRvdWJsZS5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKMFQoKSW50MzJSdWxlcxKDAQoFY29uc3QYASABKAVCdMJIcQpvCgtpbnQzMi5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEooBCgJsdBgCIAEoBUJ8wkh5CncKCGludDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEpwBCgNsdGUYAyABKAVCjAHCSIgBCoUBCglpbnQzMi5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpcHCgJndBgEIAEoBUKIB8JIhAcKegoIaW50MzIuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrMBCgtpbnQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKuwEKFWludDMyLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsMBCgxpbnQzMi5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCssBChZpbnQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLjBwoDZ3RlGAUgASgFQtMHwkjPBwqIAQoJaW50MzIuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwgEKDGludDMyLmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrKAQoWaW50MzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0gEKDWludDMyLmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2gEKF2ludDMyLmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEn8KAmluGAYgAygFQnPCSHAKbgoIaW50MzIuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEnYKBm5vdF9pbhgHIAMoBUJmwkhjCmEKDGludDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEisKB2V4YW1wbGUYCCADKAVCGsJIFwoVCg1pbnQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKMFQoKSW50NjRSdWxlcxKDAQoFY29uc3QYASABKANCdMJIcQpvCgtpbnQ2NC5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEooBCgJsdBgCIAEoA0J8wkh5CncKCGludDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEpwBCgNsdGUYAyABKANCjAHCSIgBCoUBCglpbnQ2NC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEpcHCgJndBgEIAEoA0KIB8JIhAcKegoIaW50NjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrMBCgtpbnQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKuwEKFWludDY0Lmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCsMBCgxpbnQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCssBChZpbnQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLjBwoDZ3RlGAUgASgDQtMHwkjPBwqIAQoJaW50NjQuZ3RlGnshaGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8IHJ1bGVzLmd0ZT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZV0pIDogJycKwgEKDGludDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrKAQoWaW50NjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0gEKDWludDY0Lmd0ZV9sdGUawAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3RlICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJycK2gEKF2ludDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEn8KAmluGAYgAygDQnPCSHAKbgoIaW50NjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEnYKBm5vdF9pbhgHIAMoA0JmwkhjCmEKDGludDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEisKB2V4YW1wbGUYCSADKANCGsJIFwoVCg1pbnQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKeFQoLVUludDMyUnVsZXMShAEKBWNvbnN0GAEgASgNQnXCSHIKcAoMdWludDMyLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSiwEKAmx0GAIgASgNQn3CSHoKeAoJdWludDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKA1CjQHCSIkBCoYBCgp1aW50MzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKA1CjQfCSIkHCnsKCXVpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHVpbnQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnVpbnQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNdWludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3VpbnQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgNQtgHwkjUBwqJAQoKdWludDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg11aW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChd1aW50MzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnVpbnQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChh1aW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgAEKAmluGAYgAygNQnTCSHEKbwoJdWludDMyLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YByADKA1CZ8JIZApiCg11aW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoDUIbwkgYChYKDnVpbnQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKeFQoLVUludDY0UnVsZXMShAEKBWNvbnN0GAEgASgEQnXCSHIKcAoMdWludDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSiwEKAmx0GAIgASgEQn3CSHoKeAoJdWludDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKARCjQHCSIkBCoYBCgp1aW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKARCjQfCSIkHCnsKCXVpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHVpbnQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnVpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNdWludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3VpbnQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgEQtgHwkjUBwqJAQoKdWludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg11aW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChd1aW50NjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnVpbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChh1aW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgAEKAmluGAYgAygEQnTCSHEKbwoJdWludDY0LmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YByADKARCZ8JIZApiCg11aW50NjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoBEIbwkgYChYKDnVpbnQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKeFQoLU0ludDMyUnVsZXMShAEKBWNvbnN0GAEgASgRQnXCSHIKcAoMc2ludDMyLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSiwEKAmx0GAIgASgRQn3CSHoKeAoJc2ludDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKBFCjQHCSIkBCoYBCgpzaW50MzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKBFCjQfCSIkHCnsKCXNpbnQzMi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHNpbnQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnNpbnQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNc2ludDMyLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3NpbnQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgRQtgHwkjUBwqJAQoKc2ludDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg1zaW50MzIuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChdzaW50MzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnNpbnQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChhzaW50MzIuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgAEKAmluGAYgAygRQnTCSHEKbwoJc2ludDMyLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YByADKBFCZ8JIZApiCg1zaW50MzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoEUIbwkgYChYKDnNpbnQzMi5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKeFQoLU0ludDY0UnVsZXMShAEKBWNvbnN0GAEgASgSQnXCSHIKcAoMc2ludDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSiwEKAmx0GAIgASgSQn3CSHoKeAoJc2ludDY0Lmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp0BCgNsdGUYAyABKBJCjQHCSIkBCoYBCgpzaW50NjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKcBwoCZ3QYBCABKBJCjQfCSIkHCnsKCXNpbnQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtAEKDHNpbnQ2NC5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvAEKFnNpbnQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrEAQoNc2ludDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzAEKF3NpbnQ2NC5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLoBwoDZ3RlGAUgASgSQtgHwkjUBwqJAQoKc2ludDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsMBCg1zaW50NjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCssBChdzaW50NjQuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK0wEKDnNpbnQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtsBChhzaW50NjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESgAEKAmluGAYgAygSQnTCSHEKbwoJc2ludDY0LmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YByADKBJCZ8JIZApiCg1zaW50NjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLAoHZXhhbXBsZRgIIAMoEkIbwkgYChYKDnNpbnQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiKvFQoMRml4ZWQzMlJ1bGVzEoUBCgVjb25zdBgBIAEoB0J2wkhzCnEKDWZpeGVkMzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKMAQoCbHQYAiABKAdCfsJIewp5CgpmaXhlZDMyLmx0GmshaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+PSBydWxlcy5sdD8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmx0XSkgOiAnJ0gAEp4BCgNsdGUYAyABKAdCjgHCSIoBCocBCgtmaXhlZDMyLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASoQcKAmd0GAQgASgHQpIHwkiOBwp8CgpmaXhlZDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq1AQoNZml4ZWQzMi5ndF9sdBqjAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKvQEKF2ZpeGVkMzIuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxQEKDmZpeGVkMzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrNAQoYZml4ZWQzMi5ndF9sdGVfZXhjbHVzaXZlGrABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJydIARLtBwoDZ3RlGAUgASgHQt0HwkjZBwqKAQoLZml4ZWQzMi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrEAQoOZml4ZWQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzAEKGGZpeGVkMzIuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1AEKD2ZpeGVkMzIuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrcAQoZZml4ZWQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKBAQoCaW4YBiADKAdCdcJIcgpwCgpmaXhlZDMyLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ4CgZub3RfaW4YByADKAdCaMJIZQpjCg5maXhlZDMyLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEi0KB2V4YW1wbGUYCCADKAdCHMJIGQoXCg9maXhlZDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIq8VCgxGaXhlZDY0UnVsZXMShQEKBWNvbnN0GAEgASgGQnbCSHMKcQoNZml4ZWQ2NC5jb25zdBpgdGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEowBCgJsdBgCIAEoBkJ+wkh7CnkKCmZpeGVkNjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASngEKA2x0ZRgDIAEoBkKOAcJIigEKhwEKC2ZpeGVkNjQubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKhBwoCZ3QYBCABKAZCkgfCSI4HCnwKCmZpeGVkNjQuZ3QabiFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDw9IHJ1bGVzLmd0PyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RdKSA6ICcnCrUBCg1maXhlZDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq9AQoXZml4ZWQ2NC5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrFAQoOZml4ZWQ2NC5ndF9sdGUasgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPj0gcnVsZXMuZ3QgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnCs0BChhmaXhlZDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEu0HCgNndGUYBSABKAZC3QfCSNkHCooBCgtmaXhlZDY0Lmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsQBCg5maXhlZDY0Lmd0ZV9sdBqxAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPj0gcnVsZXMuZ3RlICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrMAQoYZml4ZWQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrUAQoPZml4ZWQ2NC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCtwBChlmaXhlZDY0Lmd0ZV9sdGVfZXhjbHVzaXZlGr4BaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlIDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJ0gBEoEBCgJpbhgGIAMoBkJ1wkhyCnAKCmZpeGVkNjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEngKBm5vdF9pbhgHIAMoBkJowkhlCmMKDmZpeGVkNjQubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLQoHZXhhbXBsZRgIIAMoBkIcwkgZChcKD2ZpeGVkNjQuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iwBUKDVNGaXhlZDMyUnVsZXMShgEKBWNvbnN0GAEgASgPQnfCSHQKcgoOc2ZpeGVkMzIuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKNAQoCbHQYAiABKA9Cf8JIfAp6CgtzZml4ZWQzMi5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABKfAQoDbHRlGAMgASgPQo8BwkiLAQqIAQoMc2ZpeGVkMzIubHRlGnghaGFzKHJ1bGVzLmd0ZSkgJiYgIWhhcyhydWxlcy5ndCkgJiYgdGhpcyA+IHJ1bGVzLmx0ZT8gJ3ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmx0ZV0pIDogJydIABKmBwoCZ3QYBCABKA9ClwfCSJMHCn0KC3NmaXhlZDMyLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq2AQoOc2ZpeGVkMzIuZ3RfbHQaowFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ICYmICh0aGlzID49IHJ1bGVzLmx0IHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCr4BChhzZml4ZWQzMi5ndF9sdF9leGNsdXNpdmUaoQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3QgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8PSBydWxlcy5ndCk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwrGAQoPc2ZpeGVkMzIuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrOAQoZc2ZpeGVkMzIuZ3RfbHRlX2V4Y2x1c2l2ZRqwAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdGUgPCB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdGVdKSA6ICcnSAES8gcKA2d0ZRgFIAEoD0LiB8JI3gcKiwEKDHNmaXhlZDMyLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsUBCg9zZml4ZWQzMi5ndGVfbHQasQFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0ID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycKzQEKGXNmaXhlZDMyLmd0ZV9sdF9leGNsdXNpdmUarwFoYXMocnVsZXMubHQpICYmIHJ1bGVzLmx0IDwgcnVsZXMuZ3RlICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPCBydWxlcy5ndGUpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCtUBChBzZml4ZWQzMi5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt0BChpzZml4ZWQzMi5ndGVfbHRlX2V4Y2x1c2l2ZRq+AWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0ZV0pIDogJydIARKCAQoCaW4YBiADKA9CdsJIcwpxCgtzZml4ZWQzMi5pbhpiISh0aGlzIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSkgPyAndmFsdWUgbXVzdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnaW4nKV0pIDogJycSeQoGbm90X2luGAcgAygPQmnCSGYKZAoPc2ZpeGVkMzIubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycSLgoHZXhhbXBsZRgIIAMoD0IdwkgaChgKEHNmaXhlZDMyLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAkILCglsZXNzX3RoYW5CDgoMZ3JlYXRlcl90aGFuIsAVCg1TRml4ZWQ2NFJ1bGVzEoYBCgVjb25zdBgBIAEoEEJ3wkh0CnIKDnNmaXhlZDY0LmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSjQEKAmx0GAIgASgQQn/CSHwKegoLc2ZpeGVkNjQubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASnwEKA2x0ZRgDIAEoEEKPAcJIiwEKiAEKDHNmaXhlZDY0Lmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASpgcKAmd0GAQgASgQQpcHwkiTBwp9CgtzZml4ZWQ2NC5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDnNmaXhlZDY0Lmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYc2ZpeGVkNjQuZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD3NmaXhlZDY0Lmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGXNmaXhlZDY0Lmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEvIHCgNndGUYBSABKBBC4gfCSN4HCosBCgxzZml4ZWQ2NC5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPc2ZpeGVkNjQuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlzZml4ZWQ2NC5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQc2ZpeGVkNjQuZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoac2ZpeGVkNjQuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESggEKAmluGAYgAygQQnbCSHMKcQoLc2ZpeGVkNjQuaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEnkKBm5vdF9pbhgHIAMoEEJpwkhmCmQKD3NmaXhlZDY0Lm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEi4KB2V4YW1wbGUYCCADKBBCHcJIGgoYChBzZml4ZWQ2NC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCCwoJbGVzc190aGFuQg4KDGdyZWF0ZXJfdGhhbiLHAQoJQm9vbFJ1bGVzEoIBCgVjb25zdBgBIAEoCEJzwkhwCm4KCmJvb2wuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxIqCgdleGFtcGxlGAIgAygIQhnCSBYKFAoMYm9vbC5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAIiiDkKC1N0cmluZ1J1bGVzEoYBCgVjb25zdBgBIAEoCUJ3wkh0CnIKDHN0cmluZy5jb25zdBpidGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBlcXVhbCBgJXNgJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSfgoDbGVuGBMgASgEQnHCSG4KbAoKc3RyaW5nLmxlbhpedWludCh0aGlzLnNpemUoKSkgIT0gcnVsZXMubGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlICVzIGNoYXJhY3RlcnMnLmZvcm1hdChbcnVsZXMubGVuXSkgOiAnJxKZAQoHbWluX2xlbhgCIAEoBEKHAcJIgwEKgAEKDnN0cmluZy5taW5fbGVuGm51aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgY2hhcmFjdGVycycuZm9ybWF0KFtydWxlcy5taW5fbGVuXSkgOiAnJxKXAQoHbWF4X2xlbhgDIAEoBEKFAcJIgQEKfwoOc3RyaW5nLm1heF9sZW4abXVpbnQodGhpcy5zaXplKCkpID4gcnVsZXMubWF4X2xlbiA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBtb3N0ICVzIGNoYXJhY3RlcnMnLmZvcm1hdChbcnVsZXMubWF4X2xlbl0pIDogJycSmwEKCWxlbl9ieXRlcxgUIAEoBEKHAcJIgwEKgAEKEHN0cmluZy5sZW5fYnl0ZXMabHVpbnQoYnl0ZXModGhpcykuc2l6ZSgpKSAhPSBydWxlcy5sZW5fYnl0ZXMgPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubGVuX2J5dGVzXSkgOiAnJxKjAQoJbWluX2J5dGVzGAQgASgEQo8BwkiLAQqIAQoQc3RyaW5nLm1pbl9ieXRlcxp0dWludChieXRlcyh0aGlzKS5zaXplKCkpIDwgcnVsZXMubWluX2J5dGVzID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlIGF0IGxlYXN0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1pbl9ieXRlc10pIDogJycSogEKCW1heF9ieXRlcxgFIAEoBEKOAcJIigEKhwEKEHN0cmluZy5tYXhfYnl0ZXMac3VpbnQoYnl0ZXModGhpcykuc2l6ZSgpKSA+IHJ1bGVzLm1heF9ieXRlcyA/ICd2YWx1ZSBsZW5ndGggbXVzdCBiZSBhdCBtb3N0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1heF9ieXRlc10pIDogJycSjQEKB3BhdHRlcm4YBiABKAlCfMJIeQp3Cg5zdHJpbmcucGF0dGVybhplIXRoaXMubWF0Y2hlcyhydWxlcy5wYXR0ZXJuKSA/ICd2YWx1ZSBkb2VzIG5vdCBtYXRjaCByZWdleCBwYXR0ZXJuIGAlc2AnLmZvcm1hdChbcnVsZXMucGF0dGVybl0pIDogJycShAEKBnByZWZpeBgHIAEoCUJ0wkhxCm8KDXN0cmluZy5wcmVmaXgaXiF0aGlzLnN0YXJ0c1dpdGgocnVsZXMucHJlZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHByZWZpeCBgJXNgJy5mb3JtYXQoW3J1bGVzLnByZWZpeF0pIDogJycSggEKBnN1ZmZpeBgIIAEoCUJywkhvCm0KDXN0cmluZy5zdWZmaXgaXCF0aGlzLmVuZHNXaXRoKHJ1bGVzLnN1ZmZpeCkgPyAndmFsdWUgZG9lcyBub3QgaGF2ZSBzdWZmaXggYCVzYCcuZm9ybWF0KFtydWxlcy5zdWZmaXhdKSA6ICcnEpABCghjb250YWlucxgJIAEoCUJ+wkh7CnkKD3N0cmluZy5jb250YWlucxpmIXRoaXMuY29udGFpbnMocnVsZXMuY29udGFpbnMpID8gJ3ZhbHVlIGRvZXMgbm90IGNvbnRhaW4gc3Vic3RyaW5nIGAlc2AnLmZvcm1hdChbcnVsZXMuY29udGFpbnNdKSA6ICcnEpgBCgxub3RfY29udGFpbnMYFyABKAlCgQHCSH4KfAoTc3RyaW5nLm5vdF9jb250YWlucxpldGhpcy5jb250YWlucyhydWxlcy5ub3RfY29udGFpbnMpID8gJ3ZhbHVlIGNvbnRhaW5zIHN1YnN0cmluZyBgJXNgJy5mb3JtYXQoW3J1bGVzLm5vdF9jb250YWluc10pIDogJycSgAEKAmluGAogAygJQnTCSHEKbwoJc3RyaW5nLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ3CgZub3RfaW4YCyADKAlCZ8JIZApiCg1zdHJpbmcubm90X2luGlF0aGlzIGluIHJ1bGVzLm5vdF9pbiA/ICd2YWx1ZSBtdXN0IG5vdCBiZSBpbiBsaXN0ICVzJy5mb3JtYXQoW3J1bGVzLm5vdF9pbl0pIDogJycS3wEKBWVtYWlsGAwgASgIQs0BwkjJAQphCgxzdHJpbmcuZW1haWwSI3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGiwhcnVsZXMuZW1haWwgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzRW1haWwoKQpkChJzdHJpbmcuZW1haWxfZW1wdHkSMnZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBlbWFpbCBhZGRyZXNzGhohcnVsZXMuZW1haWwgfHwgdGhpcyAhPSAnJ0gAEucBCghob3N0bmFtZRgNIAEoCELSAcJIzgEKZQoPc3RyaW5nLmhvc3RuYW1lEh52YWx1ZSBtdXN0IGJlIGEgdmFsaWQgaG9zdG5hbWUaMiFydWxlcy5ob3N0bmFtZSB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpCmUKFXN0cmluZy5ob3N0bmFtZV9lbXB0eRItdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3RuYW1lGh0hcnVsZXMuaG9zdG5hbWUgfHwgdGhpcyAhPSAnJ0gAEscBCgJpcBgOIAEoCEK4AcJItAEKVQoJc3RyaW5nLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxomIXJ1bGVzLmlwIHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKCkKWwoPc3RyaW5nLmlwX2VtcHR5Ei92YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgYWRkcmVzcxoXIXJ1bGVzLmlwIHx8IHRoaXMgIT0gJydIABLWAQoEaXB2NBgPIAEoCELFAcJIwQEKXAoLc3RyaW5nLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaKSFydWxlcy5pcHY0IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwKDQpCmEKEXN0cmluZy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGhkhcnVsZXMuaXB2NCB8fCB0aGlzICE9ICcnSAAS1gEKBGlwdjYYECABKAhCxQHCSMEBClwKC3N0cmluZy5pcHY2EiJ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NiBhZGRyZXNzGikhcnVsZXMuaXB2NiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcCg2KQphChFzdHJpbmcuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxoZIXJ1bGVzLmlwdjYgfHwgdGhpcyAhPSAnJ0gAEr8BCgN1cmkYESABKAhCrwHCSKsBClEKCnN0cmluZy51cmkSGXZhbHVlIG11c3QgYmUgYSB2YWxpZCBVUkkaKCFydWxlcy51cmkgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzVXJpKCkKVgoQc3RyaW5nLnVyaV9lbXB0eRIodmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIFVSSRoYIXJ1bGVzLnVyaSB8fCB0aGlzICE9ICcnSAAScAoHdXJpX3JlZhgSIAEoCEJdwkhaClgKDnN0cmluZy51cmlfcmVmEiN2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVJJIFJlZmVyZW5jZRohIXJ1bGVzLnVyaV9yZWYgfHwgdGhpcy5pc1VyaVJlZigpSAASkAIKB2FkZHJlc3MYFSABKAhC/AHCSPgBCoEBCg5zdHJpbmcuYWRkcmVzcxItdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGhvc3RuYW1lLCBvciBpcCBhZGRyZXNzGkAhcnVsZXMuYWRkcmVzcyB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0bmFtZSgpIHx8IHRoaXMuaXNJcCgpCnIKFHN0cmluZy5hZGRyZXNzX2VtcHR5Ejx2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgaG9zdG5hbWUsIG9yIGlwIGFkZHJlc3MaHCFydWxlcy5hZGRyZXNzIHx8IHRoaXMgIT0gJydIABKYAgoEdXVpZBgWIAEoCEKHAsJIgwIKpQEKC3N0cmluZy51dWlkEhp2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVVJRBp6IXJ1bGVzLnV1aWQgfHwgdGhpcyA9PSAnJyB8fCB0aGlzLm1hdGNoZXMoJ15bMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXsxMn0kJykKWQoRc3RyaW5nLnV1aWRfZW1wdHkSKXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBVVUlEGhkhcnVsZXMudXVpZCB8fCB0aGlzICE9ICcnSAAS8AEKBXR1dWlkGCEgASgIQt4BwkjaAQpzCgxzdHJpbmcudHV1aWQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCB0cmltbWVkIFVVSUQaPyFydWxlcy50dXVpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTlhLWZBLUZdezMyfSQnKQpjChJzdHJpbmcudHV1aWRfZW1wdHkSMXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCB0cmltbWVkIFVVSUQaGiFydWxlcy50dXVpZCB8fCB0aGlzICE9ICcnSAASlgIKEWlwX3dpdGhfcHJlZml4bGVuGBogASgIQvgBwkj0AQp4ChhzdHJpbmcuaXBfd2l0aF9wcmVmaXhsZW4SH3ZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUCBwcmVmaXgaOyFydWxlcy5pcF93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCgpCngKHnN0cmluZy5pcF93aXRoX3ByZWZpeGxlbl9lbXB0eRIudmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIHByZWZpeBomIXJ1bGVzLmlwX3dpdGhfcHJlZml4bGVuIHx8IHRoaXMgIT0gJydIABLPAgoTaXB2NF93aXRoX3ByZWZpeGxlbhgbIAEoCEKvAsJIqwIKkwEKGnN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuEjV2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBo+IXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCkKkgEKIHN0cmluZy5pcHY0X3dpdGhfcHJlZml4bGVuX2VtcHR5EkR2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzIHdpdGggcHJlZml4IGxlbmd0aBooIXJ1bGVzLmlwdjRfd2l0aF9wcmVmaXhsZW4gfHwgdGhpcyAhPSAnJ0gAEs8CChNpcHY2X3dpdGhfcHJlZml4bGVuGBwgASgIQq8CwkirAgqTAQoac3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW4SNXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGj4hcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCg2KQqSAQogc3RyaW5nLmlwdjZfd2l0aF9wcmVmaXhsZW5fZW1wdHkSRHZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBJUHY2IGFkZHJlc3Mgd2l0aCBwcmVmaXggbGVuZ3RoGighcnVsZXMuaXB2Nl93aXRoX3ByZWZpeGxlbiB8fCB0aGlzICE9ICcnSAAS8gEKCWlwX3ByZWZpeBgdIAEoCELcAcJI2AEKbAoQc3RyaW5nLmlwX3ByZWZpeBIfdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQIHByZWZpeBo3IXJ1bGVzLmlwX3ByZWZpeCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNJcFByZWZpeCh0cnVlKQpoChZzdHJpbmcuaXBfcHJlZml4X2VtcHR5Ei52YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVAgcHJlZml4Gh4hcnVsZXMuaXBfcHJlZml4IHx8IHRoaXMgIT0gJydIABKDAgoLaXB2NF9wcmVmaXgYHiABKAhC6wHCSOcBCnUKEnN0cmluZy5pcHY0X3ByZWZpeBIhdmFsdWUgbXVzdCBiZSBhIHZhbGlkIElQdjQgcHJlZml4GjwhcnVsZXMuaXB2NF9wcmVmaXggfHwgdGhpcyA9PSAnJyB8fCB0aGlzLmlzSXBQcmVmaXgoNCwgdHJ1ZSkKbgoYc3RyaW5nLmlwdjRfcHJlZml4X2VtcHR5EjB2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBwcmVmaXgaICFydWxlcy5pcHY0X3ByZWZpeCB8fCB0aGlzICE9ICcnSAASgwIKC2lwdjZfcHJlZml4GB8gASgIQusBwkjnAQp1ChJzdHJpbmcuaXB2Nl9wcmVmaXgSIXZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IHByZWZpeBo8IXJ1bGVzLmlwdjZfcHJlZml4IHx8IHRoaXMgPT0gJycgfHwgdGhpcy5pc0lwUHJlZml4KDYsIHRydWUpCm4KGHN0cmluZy5pcHY2X3ByZWZpeF9lbXB0eRIwdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgcHJlZml4GiAhcnVsZXMuaXB2Nl9wcmVmaXggfHwgdGhpcyAhPSAnJ0gAErUCCg1ob3N0X2FuZF9wb3J0GCAgASgIQpsCwkiXAgqZAQoUc3RyaW5nLmhvc3RfYW5kX3BvcnQSQXZhbHVlIG11c3QgYmUgYSB2YWxpZCBob3N0IChob3N0bmFtZSBvciBJUCBhZGRyZXNzKSBhbmQgcG9ydCBwYWlyGj4hcnVsZXMuaG9zdF9hbmRfcG9ydCB8fCB0aGlzID09ICcnIHx8IHRoaXMuaXNIb3N0QW5kUG9ydCh0cnVlKQp5ChpzdHJpbmcuaG9zdF9hbmRfcG9ydF9lbXB0eRI3dmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIGhvc3QgYW5kIHBvcnQgcGFpchoiIXJ1bGVzLmhvc3RfYW5kX3BvcnQgfHwgdGhpcyAhPSAnJ0gAEvUBCgR1bGlkGCMgASgIQuQBwkjgAQqCAQoLc3RyaW5nLnVsaWQSGnZhbHVlIG11c3QgYmUgYSB2YWxpZCBVTElEGlchcnVsZXMudWxpZCB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcygnXlswLTddWzAtOUEtSEpLTU5QLVRWLVphLWhqa21ucC10di16XXsyNX0kJykKWQoRc3RyaW5nLnVsaWRfZW1wdHkSKXZhbHVlIGlzIGVtcHR5LCB3aGljaCBpcyBub3QgYSB2YWxpZCBVTElEGhkhcnVsZXMudWxpZCB8fCB0aGlzICE9ICcnSAASqAUKEHdlbGxfa25vd25fcmVnZXgYGCABKA4yGC5idWYudmFsaWRhdGUuS25vd25SZWdleELxBMJI7QQK8AEKI3N0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lEiZ2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRqgAXJ1bGVzLndlbGxfa25vd25fcmVnZXggIT0gMSB8fCB0aGlzID09ICcnIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXjo/WzAtOWEtekEtWiEjJCUmXCcqKy0uXl98flx4NjBdKyQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSskJykKjQEKKXN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl9uYW1lX2VtcHR5EjV2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSFRUUCBoZWFkZXIgbmFtZRopcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAxIHx8IHRoaXMgIT0gJycK5wEKJHN0cmluZy53ZWxsX2tub3duX3JlZ2V4LmhlYWRlcl92YWx1ZRIndmFsdWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgaGVhZGVyIHZhbHVlGpUBcnVsZXMud2VsbF9rbm93bl9yZWdleCAhPSAyIHx8IHRoaXMubWF0Y2hlcyghaGFzKHJ1bGVzLnN0cmljdCkgfHwgcnVsZXMuc3RyaWN0ID8nXlteXHUwMDAwLVx1MDAwOFx1MDAwQS1cdTAwMUZcdTAwN0ZdKiQnIDonXlteXHUwMDAwXHUwMDBBXHUwMDBEXSokJylIABIOCgZzdHJpY3QYGSABKAgSLAoHZXhhbXBsZRgiIAMoCUIbwkgYChYKDnN0cmluZy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLCEgoKQnl0ZXNSdWxlcxKAAQoFY29uc3QYASABKAxCccJIbgpsCgtieXRlcy5jb25zdBpddGhpcyAhPSBnZXRGaWVsZChydWxlcywgJ2NvbnN0JykgPyAndmFsdWUgbXVzdCBiZSAleCcuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2NvbnN0JyldKSA6ICcnEngKA2xlbhgNIAEoBEJrwkhoCmYKCWJ5dGVzLmxlbhpZdWludCh0aGlzLnNpemUoKSkgIT0gcnVsZXMubGVuID8gJ3ZhbHVlIGxlbmd0aCBtdXN0IGJlICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLmxlbl0pIDogJycSkAEKB21pbl9sZW4YAiABKARCf8JIfAp6Cg1ieXRlcy5taW5fbGVuGml1aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9sZW4gPyAndmFsdWUgbGVuZ3RoIG11c3QgYmUgYXQgbGVhc3QgJXMgYnl0ZXMnLmZvcm1hdChbcnVsZXMubWluX2xlbl0pIDogJycSiAEKB21heF9sZW4YAyABKARCd8JIdApyCg1ieXRlcy5tYXhfbGVuGmF1aW50KHRoaXMuc2l6ZSgpKSA+IHJ1bGVzLm1heF9sZW4gPyAndmFsdWUgbXVzdCBiZSBhdCBtb3N0ICVzIGJ5dGVzJy5mb3JtYXQoW3J1bGVzLm1heF9sZW5dKSA6ICcnEpABCgdwYXR0ZXJuGAQgASgJQn/CSHwKegoNYnl0ZXMucGF0dGVybhppIXN0cmluZyh0aGlzKS5tYXRjaGVzKHJ1bGVzLnBhdHRlcm4pID8gJ3ZhbHVlIG11c3QgbWF0Y2ggcmVnZXggcGF0dGVybiBgJXNgJy5mb3JtYXQoW3J1bGVzLnBhdHRlcm5dKSA6ICcnEoEBCgZwcmVmaXgYBSABKAxCccJIbgpsCgxieXRlcy5wcmVmaXgaXCF0aGlzLnN0YXJ0c1dpdGgocnVsZXMucHJlZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHByZWZpeCAleCcuZm9ybWF0KFtydWxlcy5wcmVmaXhdKSA6ICcnEn8KBnN1ZmZpeBgGIAEoDEJvwkhsCmoKDGJ5dGVzLnN1ZmZpeBpaIXRoaXMuZW5kc1dpdGgocnVsZXMuc3VmZml4KSA/ICd2YWx1ZSBkb2VzIG5vdCBoYXZlIHN1ZmZpeCAleCcuZm9ybWF0KFtydWxlcy5zdWZmaXhdKSA6ICcnEoMBCghjb250YWlucxgHIAEoDEJxwkhuCmwKDmJ5dGVzLmNvbnRhaW5zGlohdGhpcy5jb250YWlucyhydWxlcy5jb250YWlucykgPyAndmFsdWUgZG9lcyBub3QgY29udGFpbiAleCcuZm9ybWF0KFtydWxlcy5jb250YWluc10pIDogJycSpwEKAmluGAggAygMQpoBwkiWAQqTAQoIYnl0ZXMuaW4ahgFnZXRGaWVsZChydWxlcywgJ2luJykuc2l6ZSgpID4gMCAmJiAhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ2CgZub3RfaW4YCSADKAxCZsJIYwphCgxieXRlcy5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxLrAQoCaXAYCiABKAhC3AHCSNgBCnQKCGJ5dGVzLmlwEiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgSVAgYWRkcmVzcxpGIXJ1bGVzLmlwIHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNCB8fCB0aGlzLnNpemUoKSA9PSAxNgpgCg5ieXRlcy5pcF9lbXB0eRIvdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQIGFkZHJlc3MaHSFydWxlcy5pcCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5AEKBGlwdjQYCyABKAhC0wHCSM8BCmUKCmJ5dGVzLmlwdjQSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY0IGFkZHJlc3MaMyFydWxlcy5pcHY0IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gNApmChBieXRlcy5pcHY0X2VtcHR5EjF2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzGh8hcnVsZXMuaXB2NCB8fCB0aGlzLnNpemUoKSAhPSAwSAAS5QEKBGlwdjYYDCABKAhC1AHCSNABCmYKCmJ5dGVzLmlwdjYSInZhbHVlIG11c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MaNCFydWxlcy5pcHY2IHx8IHRoaXMuc2l6ZSgpID09IDAgfHwgdGhpcy5zaXplKCkgPT0gMTYKZgoQYnl0ZXMuaXB2Nl9lbXB0eRIxdmFsdWUgaXMgZW1wdHksIHdoaWNoIGlzIG5vdCBhIHZhbGlkIElQdjYgYWRkcmVzcxofIXJ1bGVzLmlwdjYgfHwgdGhpcy5zaXplKCkgIT0gMEgAEtUBCgR1dWlkGA8gASgIQsQBwkjAAQpeCgpieXRlcy51dWlkEhp2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgVVVJRBo0IXJ1bGVzLnV1aWQgfHwgdGhpcy5zaXplKCkgPT0gMCB8fCB0aGlzLnNpemUoKSA9PSAxNgpeChBieXRlcy51dWlkX2VtcHR5Eil2YWx1ZSBpcyBlbXB0eSwgd2hpY2ggaXMgbm90IGEgdmFsaWQgVVVJRBofIXJ1bGVzLnV1aWQgfHwgdGhpcy5zaXplKCkgIT0gMEgAEisKB2V4YW1wbGUYDiADKAxCGsJIFwoVCg1ieXRlcy5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAJCDAoKd2VsbF9rbm93biLUAwoJRW51bVJ1bGVzEoIBCgVjb25zdBgBIAEoBUJzwkhwCm4KCmVudW0uY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxIUCgxkZWZpbmVkX29ubHkYAiABKAgSfgoCaW4YAyADKAVCcsJIbwptCgdlbnVtLmluGmIhKHRoaXMgaW4gZ2V0RmllbGQocnVsZXMsICdpbicpKSA/ICd2YWx1ZSBtdXN0IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdpbicpXSkgOiAnJxJ1CgZub3RfaW4YBCADKAVCZcJIYgpgCgtlbnVtLm5vdF9pbhpRdGhpcyBpbiBydWxlcy5ub3RfaW4gPyAndmFsdWUgbXVzdCBub3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtydWxlcy5ub3RfaW5dKSA6ICcnEioKB2V4YW1wbGUYBSADKAVCGcJIFgoUCgxlbnVtLmV4YW1wbGUaBHRydWUqCQjoBxCAgICAAiL7AwoNUmVwZWF0ZWRSdWxlcxKeAQoJbWluX2l0ZW1zGAEgASgEQooBwkiGAQqDAQoScmVwZWF0ZWQubWluX2l0ZW1zGm11aW50KHRoaXMuc2l6ZSgpKSA8IHJ1bGVzLm1pbl9pdGVtcyA/ICd2YWx1ZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3QgJWQgaXRlbShzKScuZm9ybWF0KFtydWxlcy5taW5faXRlbXNdKSA6ICcnEqIBCgltYXhfaXRlbXMYAiABKARCjgHCSIoBCocBChJyZXBlYXRlZC5tYXhfaXRlbXMacXVpbnQodGhpcy5zaXplKCkpID4gcnVsZXMubWF4X2l0ZW1zID8gJ3ZhbHVlIG11c3QgY29udGFpbiBubyBtb3JlIHRoYW4gJXMgaXRlbShzKScuZm9ybWF0KFtydWxlcy5tYXhfaXRlbXNdKSA6ICcnEnAKBnVuaXF1ZRgDIAEoCEJgwkhdClsKD3JlcGVhdGVkLnVuaXF1ZRIocmVwZWF0ZWQgdmFsdWUgbXVzdCBjb250YWluIHVuaXF1ZSBpdGVtcxoeIXJ1bGVzLnVuaXF1ZSB8fCB0aGlzLnVuaXF1ZSgpEicKBWl0ZW1zGAQgASgLMhguYnVmLnZhbGlkYXRlLkZpZWxkUnVsZXMqCQjoBxCAgICAAiKKAwoITWFwUnVsZXMSjwEKCW1pbl9wYWlycxgBIAEoBEJ8wkh5CncKDW1hcC5taW5fcGFpcnMaZnVpbnQodGhpcy5zaXplKCkpIDwgcnVsZXMubWluX3BhaXJzID8gJ21hcCBtdXN0IGJlIGF0IGxlYXN0ICVkIGVudHJpZXMnLmZvcm1hdChbcnVsZXMubWluX3BhaXJzXSkgOiAnJxKOAQoJbWF4X3BhaXJzGAIgASgEQnvCSHgKdgoNbWFwLm1heF9wYWlycxpldWludCh0aGlzLnNpemUoKSkgPiBydWxlcy5tYXhfcGFpcnMgPyAnbWFwIG11c3QgYmUgYXQgbW9zdCAlZCBlbnRyaWVzJy5mb3JtYXQoW3J1bGVzLm1heF9wYWlyc10pIDogJycSJgoEa2V5cxgEIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzEigKBnZhbHVlcxgFIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzKgkI6AcQgICAgAIiJgoIQW55UnVsZXMSCgoCaW4YAiADKAkSDgoGbm90X2luGAMgAygJIpkXCg1EdXJhdGlvblJ1bGVzEqEBCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkJ3wkh0CnIKDmR1cmF0aW9uLmNvbnN0GmB0aGlzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKSA/ICd2YWx1ZSBtdXN0IGVxdWFsICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKV0pIDogJycSqAEKAmx0GAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQn/CSHwKegoLZHVyYXRpb24ubHQaayFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID49IHJ1bGVzLmx0PyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMubHRdKSA6ICcnSAASugEKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkKPAcJIiwEKiAEKDGR1cmF0aW9uLmx0ZRp4IWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPiBydWxlcy5sdGU/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5sdGVdKSA6ICcnSAASwQcKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQpcHwkiTBwp9CgtkdXJhdGlvbi5ndBpuIWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPD0gcnVsZXMuZ3Q/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndF0pIDogJycKtgEKDmR1cmF0aW9uLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq+AQoYZHVyYXRpb24uZ3RfbHRfZXhjbHVzaXZlGqEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ICYmIChydWxlcy5sdCA8PSB0aGlzICYmIHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgb3IgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0LCBydWxlcy5sdF0pIDogJycKxgEKD2R1cmF0aW9uLmd0X2x0ZRqyAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndCAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0ZV0pIDogJycKzgEKGWR1cmF0aW9uLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEo0ICgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25C4gfCSN4HCosBCgxkdXJhdGlvbi5ndGUaeyFoYXMocnVsZXMubHQpICYmICFoYXMocnVsZXMubHRlKSAmJiB0aGlzIDwgcnVsZXMuZ3RlPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlXSkgOiAnJwrFAQoPZHVyYXRpb24uZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs0BChlkdXJhdGlvbi5ndGVfbHRfZXhjbHVzaXZlGq8BaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA8IHJ1bGVzLmd0ZSAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndGUsIHJ1bGVzLmx0XSkgOiAnJwrVAQoQZHVyYXRpb24uZ3RlX2x0ZRrAAWhhcyhydWxlcy5sdGUpICYmIHJ1bGVzLmx0ZSA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPiBydWxlcy5sdGUgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRlXSkgOiAnJwrdAQoaZHVyYXRpb24uZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESnQEKAmluGAcgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQnbCSHMKcQoLZHVyYXRpb24uaW4aYiEodGhpcyBpbiBnZXRGaWVsZChydWxlcywgJ2luJykpID8gJ3ZhbHVlIG11c3QgYmUgaW4gbGlzdCAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEpQBCgZub3RfaW4YCCADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25CacJIZgpkCg9kdXJhdGlvbi5ub3RfaW4aUXRoaXMgaW4gcnVsZXMubm90X2luID8gJ3ZhbHVlIG11c3Qgbm90IGJlIGluIGxpc3QgJXMnLmZvcm1hdChbcnVsZXMubm90X2luXSkgOiAnJxJJCgdleGFtcGxlGAkgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQh3CSBoKGAoQZHVyYXRpb24uZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4i/QUKDkZpZWxkTWFza1J1bGVzEr8BCgVjb25zdBgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCkwHCSI8BCowBChBmaWVsZF9tYXNrLmNvbnN0Gnh0aGlzLnBhdGhzICE9IGdldEZpZWxkKHJ1bGVzLCAnY29uc3QnKS5wYXRocyA/ICd2YWx1ZSBtdXN0IGVxdWFsIHBhdGhzICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnY29uc3QnKS5wYXRoc10pIDogJycS2QEKAmluGAIgAygJQswBwkjIAQrFAQoNZmllbGRfbWFzay5pbhqzASF0aGlzLnBhdGhzLmFsbChwLCBwIGluIGdldEZpZWxkKHJ1bGVzLCAnaW4nKSB8fCBnZXRGaWVsZChydWxlcywgJ2luJykuZXhpc3RzKGYsIHAuc3RhcnRzV2l0aChmKycuJykpKSA/ICd2YWx1ZSBtdXN0IG9ubHkgY29udGFpbiBwYXRocyBpbiAlcycuZm9ybWF0KFtnZXRGaWVsZChydWxlcywgJ2luJyldKSA6ICcnEvMBCgZub3RfaW4YAyADKAlC4gHCSN4BCtsBChFmaWVsZF9tYXNrLm5vdF9pbhrFASF0aGlzLnBhdGhzLmFsbChwLCAhKHAgaW4gZ2V0RmllbGQocnVsZXMsICdub3RfaW4nKSB8fCBnZXRGaWVsZChydWxlcywgJ25vdF9pbicpLmV4aXN0cyhmLCBwLnN0YXJ0c1dpdGgoZisnLicpKSkpID8gJ3ZhbHVlIG11c3Qgbm90IGNvbnRhaW4gYW55IHBhdGhzIGluICVzJy5mb3JtYXQoW2dldEZpZWxkKHJ1bGVzLCAnbm90X2luJyldKSA6ICcnEkwKB2V4YW1wbGUYBCADKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQh/CSBwKGgoSZmllbGRfbWFzay5leGFtcGxlGgR0cnVlKgkI6AcQgICAgAIikhgKDlRpbWVzdGFtcFJ1bGVzEqMBCgVjb25zdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCeMJIdQpzCg90aW1lc3RhbXAuY29uc3QaYHRoaXMgIT0gZ2V0RmllbGQocnVsZXMsICdjb25zdCcpID8gJ3ZhbHVlIG11c3QgZXF1YWwgJXMnLmZvcm1hdChbZ2V0RmllbGQocnVsZXMsICdjb25zdCcpXSkgOiAnJxKrAQoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQoABwkh9CnsKDHRpbWVzdGFtcC5sdBprIWhhcyhydWxlcy5ndGUpICYmICFoYXMocnVsZXMuZ3QpICYmIHRoaXMgPj0gcnVsZXMubHQ/ICd2YWx1ZSBtdXN0IGJlIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5sdF0pIDogJydIABK8AQoDbHRlGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKQAcJIjAEKiQEKDXRpbWVzdGFtcC5sdGUaeCFoYXMocnVsZXMuZ3RlKSAmJiAhaGFzKHJ1bGVzLmd0KSAmJiB0aGlzID4gcnVsZXMubHRlPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMubHRlXSkgOiAnJ0gAEmwKBmx0X25vdxgHIAEoCEJawkhXClUKEHRpbWVzdGFtcC5sdF9ub3caQShydWxlcy5sdF9ub3cgJiYgdGhpcyA+IG5vdykgPyAndmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gbm93JyA6ICcnSAASxwcKAmd0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEKcB8JImAcKfgoMdGltZXN0YW1wLmd0Gm4haGFzKHJ1bGVzLmx0KSAmJiAhaGFzKHJ1bGVzLmx0ZSkgJiYgdGhpcyA8PSBydWxlcy5ndD8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0XSkgOiAnJwq3AQoPdGltZXN0YW1wLmd0X2x0GqMBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndCAmJiAodGhpcyA+PSBydWxlcy5sdCB8fCB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIGFuZCBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3QsIHJ1bGVzLmx0XSkgOiAnJwq/AQoZdGltZXN0YW1wLmd0X2x0X2V4Y2x1c2l2ZRqhAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndCAmJiAocnVsZXMubHQgPD0gdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRdKSA6ICcnCscBChB0aW1lc3RhbXAuZ3RfbHRlGrIBaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ICYmICh0aGlzID4gcnVsZXMubHRlIHx8IHRoaXMgPD0gcnVsZXMuZ3QpPyAndmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJwrPAQoadGltZXN0YW1wLmd0X2x0ZV9leGNsdXNpdmUasAFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndCAmJiAocnVsZXMubHRlIDwgdGhpcyAmJiB0aGlzIDw9IHJ1bGVzLmd0KT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVzIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndCwgcnVsZXMubHRlXSkgOiAnJ0gBEpMICgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQucHwkjjBwqMAQoNdGltZXN0YW1wLmd0ZRp7IWhhcyhydWxlcy5sdCkgJiYgIWhhcyhydWxlcy5sdGUpICYmIHRoaXMgPCBydWxlcy5ndGU/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcycuZm9ybWF0KFtydWxlcy5ndGVdKSA6ICcnCsYBChB0aW1lc3RhbXAuZ3RlX2x0GrEBaGFzKHJ1bGVzLmx0KSAmJiBydWxlcy5sdCA+PSBydWxlcy5ndGUgJiYgKHRoaXMgPj0gcnVsZXMubHQgfHwgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuICVzJy5mb3JtYXQoW3J1bGVzLmd0ZSwgcnVsZXMubHRdKSA6ICcnCs4BChp0aW1lc3RhbXAuZ3RlX2x0X2V4Y2x1c2l2ZRqvAWhhcyhydWxlcy5sdCkgJiYgcnVsZXMubHQgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0IDw9IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdF0pIDogJycK1gEKEXRpbWVzdGFtcC5ndGVfbHRlGsABaGFzKHJ1bGVzLmx0ZSkgJiYgcnVsZXMubHRlID49IHJ1bGVzLmd0ZSAmJiAodGhpcyA+IHJ1bGVzLmx0ZSB8fCB0aGlzIDwgcnVsZXMuZ3RlKT8gJ3ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnCt4BCht0aW1lc3RhbXAuZ3RlX2x0ZV9leGNsdXNpdmUavgFoYXMocnVsZXMubHRlKSAmJiBydWxlcy5sdGUgPCBydWxlcy5ndGUgJiYgKHJ1bGVzLmx0ZSA8IHRoaXMgJiYgdGhpcyA8IHJ1bGVzLmd0ZSk/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMnLmZvcm1hdChbcnVsZXMuZ3RlLCBydWxlcy5sdGVdKSA6ICcnSAESbwoGZ3Rfbm93GAggASgIQl3CSFoKWAoQdGltZXN0YW1wLmd0X25vdxpEKHJ1bGVzLmd0X25vdyAmJiB0aGlzIDwgbm93KSA/ICd2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBub3cnIDogJydIARK4AQoGd2l0aGluGAkgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQowBwkiIAQqFAQoQdGltZXN0YW1wLndpdGhpbhpxdGhpcyA8IG5vdy1ydWxlcy53aXRoaW4gfHwgdGhpcyA+IG5vdytydWxlcy53aXRoaW4gPyAndmFsdWUgbXVzdCBiZSB3aXRoaW4gJXMgb2Ygbm93Jy5mb3JtYXQoW3J1bGVzLndpdGhpbl0pIDogJycSSwoHZXhhbXBsZRgKIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCHsJIGwoZChF0aW1lc3RhbXAuZXhhbXBsZRoEdHJ1ZSoJCOgHEICAgIACQgsKCWxlc3NfdGhhbkIOCgxncmVhdGVyX3RoYW4iOQoKVmlvbGF0aW9ucxIrCgp2aW9sYXRpb25zGAEgAygLMhcuYnVmLnZhbGlkYXRlLlZpb2xhdGlvbiKfAQoJVmlvbGF0aW9uEiYKBWZpZWxkGAUgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIlCgRydWxlGAYgASgLMhcuYnVmLnZhbGlkYXRlLkZpZWxkUGF0aBIPCgdydWxlX2lkGAIgASgJEg8KB21lc3NhZ2UYAyABKAkSDwoHZm9yX2tleRgEIAEoCEoECAEQAlIKZmllbGRfcGF0aCI9CglGaWVsZFBhdGgSMAoIZWxlbWVudHMYASADKAsyHi5idWYudmFsaWRhdGUuRmllbGRQYXRoRWxlbWVudCLpAgoQRmllbGRQYXRoRWxlbWVudBIUCgxmaWVsZF9udW1iZXIYASABKAUSEgoKZmllbGRfbmFtZRgCIAEoCRI+CgpmaWVsZF90eXBlGAMgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSPAoIa2V5X3R5cGUYBCABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRI+Cgp2YWx1ZV90eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUSDwoFaW5kZXgYBiABKARIABISCghib29sX2tleRgHIAEoCEgAEhEKB2ludF9rZXkYCCABKANIABISCgh1aW50X2tleRgJIAEoBEgAEhQKCnN0cmluZ19rZXkYCiABKAlIAEILCglzdWJzY3JpcHQqoQEKBklnbm9yZRIWChJJR05PUkVfVU5TUEVDSUZJRUQQABIYChRJR05PUkVfSUZfWkVST19WQUxVRRABEhEKDUlHTk9SRV9BTFdBWVMQAyIECAIQAioMSUdOT1JFX0VNUFRZKg5JR05PUkVfREVGQVVMVCoXSUdOT1JFX0lGX0RFRkFVTFRfVkFMVUUqFUlHTk9SRV9JRl9VTlBPUFVMQVRFRCpuCgpLbm93blJlZ2V4EhsKF0tOT1dOX1JFR0VYX1VOU1BFQ0lGSUVEEAASIAocS05PV05fUkVHRVhfSFRUUF9IRUFERVJfTkFNRRABEiEKHUtOT1dOX1JFR0VYX0hUVFBfSEVBREVSX1ZBTFVFEAI6VgoHbWVzc2FnZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiHCSABKAsyGi5idWYudmFsaWRhdGUuTWVzc2FnZVJ1bGVzUgdtZXNzYWdlOk4KBW9uZW9mEh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9ucxiHCSABKAsyGC5idWYudmFsaWRhdGUuT25lb2ZSdWxlc1IFb25lb2Y6TgoFZmllbGQSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGIcJIAEoCzIYLmJ1Zi52YWxpZGF0ZS5GaWVsZFJ1bGVzUgVmaWVsZDpdCgpwcmVkZWZpbmVkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiICSABKAsyHS5idWYudmFsaWRhdGUuUHJlZGVmaW5lZFJ1bGVzUgpwcmVkZWZpbmVkQrsBChBjb20uYnVmLnZhbGlkYXRlQg1WYWxpZGF0ZVByb3RvUAFaR2J1Zi5idWlsZC9nZW4vZ28vYnVmYnVpbGQvcHJvdG92YWxpZGF0ZS9wcm90b2NvbGJ1ZmZlcnMvZ28vYnVmL3ZhbGlkYXRlogIDQlZYqgIMQnVmLlZhbGlkYXRlygIMQnVmXFZhbGlkYXRl4gIYQnVmXFZhbGlkYXRlXEdQQk1ldGFkYXRh6gINQnVmOjpWYWxpZGF0ZQ", [file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); + +/** + * `Rule` represents a validation rule written in the Common Expression + * Language (CEL) syntax. Each Rule includes a unique identifier, an + * optional error message, and the CEL expression to evaluate. For more + * information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + * + * ```proto + * message Foo { + * option (buf.validate.message).cel = { + * id: "foo.bar" + * message: "bar must be greater than 0" + * expression: "this.bar > 0" + * }; + * int32 bar = 1; + * } + * ``` + * + * @generated from message buf.validate.Rule + */ +export type Rule = Message<"buf.validate.Rule"> & { + /** + * `id` is a string that serves as a machine-readable name for this Rule. + * It should be unique within its scope, which could be either a message or a field. + * + * @generated from field: optional string id = 1; + */ + id: string; + + /** + * `message` is an optional field that provides a human-readable error message + * for this Rule when the CEL expression evaluates to false. If a + * non-empty message is provided, any strings resulting from the CEL + * expression evaluation are ignored. + * + * @generated from field: optional string message = 2; + */ + message: string; + + /** + * `expression` is the actual CEL expression that will be evaluated for + * validation. This string must resolve to either a boolean or a string + * value. If the expression evaluates to false or a non-empty string, the + * validation is considered failed, and the message is rejected. + * + * @generated from field: optional string expression = 3; + */ + expression: string; +}; + +/** + * Describes the message buf.validate.Rule. + * Use `create(RuleSchema)` to create a new message. + */ +export const RuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 0); + +/** + * MessageRules represents validation rules that are applied to the entire message. + * It includes disabling options and a list of Rule messages representing Common Expression Language (CEL) validation rules. + * + * @generated from message buf.validate.MessageRules + */ +export type MessageRules = Message<"buf.validate.MessageRules"> & { + /** + * `cel_expression` is a repeated field CEL expressions. Each expression specifies a validation + * rule to be applied to this message. These rules are written in Common Expression Language (CEL) syntax. + * + * This is a simplified form of the `cel` Rule field, where only `expression` is set. This allows for + * simpler syntax when defining CEL Rules where `id` and `message` derived from the `expression`. `id` will + * be same as the `expression`. + * + * For more information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + * + * ```proto + * message MyMessage { + * // The field `foo` must be greater than 42. + * option (buf.validate.message).cel_expression = "this.foo > 42"; + * // The field `foo` must be less than 84. + * option (buf.validate.message).cel_expression = "this.foo < 84"; + * optional int32 foo = 1; + * } + * ``` + * + * @generated from field: repeated string cel_expression = 5; + */ + celExpression: string[]; + + /** + * `cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message. + * These rules are written in Common Expression Language (CEL) syntax. For more information, + * [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + * + * + * ```proto + * message MyMessage { + * // The field `foo` must be greater than 42. + * option (buf.validate.message).cel = { + * id: "my_message.value", + * message: "value must be greater than 42", + * expression: "this.foo > 42", + * }; + * optional int32 foo = 1; + * } + * ``` + * + * @generated from field: repeated buf.validate.Rule cel = 3; + */ + cel: Rule[]; + + /** + * `oneof` is a repeated field of type MessageOneofRule that specifies a list of fields + * of which at most one can be present. If `required` is also specified, then exactly one + * of the specified fields _must_ be present. + * + * This will enforce oneof-like constraints with a few features not provided by + * actual Protobuf oneof declarations: + * 1. Repeated and map fields are allowed in this validation. In a Protobuf oneof, + * only scalar fields are allowed. + * 2. Fields with implicit presence are allowed. In a Protobuf oneof, all member + * fields have explicit presence. This means that, for the purpose of determining + * how many fields are set, explicitly setting such a field to its zero value is + * effectively the same as not setting it at all. + * 3. This will always generate validation errors for a message unmarshalled from + * serialized data that sets more than one field. With a Protobuf oneof, when + * multiple fields are present in the serialized form, earlier values are usually + * silently ignored when unmarshalling, with only the last field being set when + * unmarshalling completes. + * + * Note that adding a field to a `oneof` will also set the IGNORE_IF_ZERO_VALUE on the fields. This means + * only the field that is set will be validated and the unset fields are not validated according to the field rules. + * This behavior can be overridden by setting `ignore` against a field. + * + * ```proto + * message MyMessage { + * // Only one of `field1` or `field2` _can_ be present in this message. + * option (buf.validate.message).oneof = { fields: ["field1", "field2"] }; + * // Exactly one of `field3` or `field4` _must_ be present in this message. + * option (buf.validate.message).oneof = { fields: ["field3", "field4"], required: true }; + * string field1 = 1; + * bytes field2 = 2; + * bool field3 = 3; + * int32 field4 = 4; + * } + * ``` + * + * @generated from field: repeated buf.validate.MessageOneofRule oneof = 4; + */ + oneof: MessageOneofRule[]; +}; + +/** + * Describes the message buf.validate.MessageRules. + * Use `create(MessageRulesSchema)` to create a new message. + */ +export const MessageRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 1); + +/** + * @generated from message buf.validate.MessageOneofRule + */ +export type MessageOneofRule = Message<"buf.validate.MessageOneofRule"> & { + /** + * A list of field names to include in the oneof. All field names must be + * defined in the message. At least one field must be specified, and + * duplicates are not permitted. + * + * @generated from field: repeated string fields = 1; + */ + fields: string[]; + + /** + * If true, one of the fields specified _must_ be set. + * + * @generated from field: optional bool required = 2; + */ + required: boolean; +}; + +/** + * Describes the message buf.validate.MessageOneofRule. + * Use `create(MessageOneofRuleSchema)` to create a new message. + */ +export const MessageOneofRuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 2); + +/** + * The `OneofRules` message type enables you to manage rules for + * oneof fields in your protobuf messages. + * + * @generated from message buf.validate.OneofRules + */ +export type OneofRules = Message<"buf.validate.OneofRules"> & { + /** + * If `required` is true, exactly one field of the oneof must be set. A + * validation error is returned if no fields in the oneof are set. Further rules + * should be placed on the fields themselves to ensure they are valid values, + * such as `min_len` or `gt`. + * + * ```proto + * message MyMessage { + * oneof value { + * // Either `a` or `b` must be set. If `a` is set, it must also be + * // non-empty; whereas if `b` is set, it can still be an empty string. + * option (buf.validate.oneof).required = true; + * string a = 1 [(buf.validate.field).string.min_len = 1]; + * string b = 2; + * } + * } + * ``` + * + * @generated from field: optional bool required = 1; + */ + required: boolean; +}; + +/** + * Describes the message buf.validate.OneofRules. + * Use `create(OneofRulesSchema)` to create a new message. + */ +export const OneofRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 3); + +/** + * FieldRules encapsulates the rules for each type of field. Depending on + * the field, the correct set should be used to ensure proper validations. + * + * @generated from message buf.validate.FieldRules + */ +export type FieldRules = Message<"buf.validate.FieldRules"> & { + /** + * `cel_expression` is a repeated field CEL expressions. Each expression specifies a validation + * rule to be applied to this message. These rules are written in Common Expression Language (CEL) syntax. + * + * This is a simplified form of the `cel` Rule field, where only `expression` is set. This allows for + * simpler syntax when defining CEL Rules where `id` and `message` derived from the `expression`. `id` will + * be same as the `expression`. + * + * For more information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + * + * ```proto + * message MyMessage { + * // The field `value` must be greater than 42. + * optional int32 value = 1 [(buf.validate.field).cel_expression = "this > 42"]; + * } + * ``` + * + * @generated from field: repeated string cel_expression = 29; + */ + celExpression: string[]; + + /** + * `cel` is a repeated field used to represent a textual expression + * in the Common Expression Language (CEL) syntax. For more information, + * [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + * + * ```proto + * message MyMessage { + * // The field `value` must be greater than 42. + * optional int32 value = 1 [(buf.validate.field).cel = { + * id: "my_message.value", + * message: "value must be greater than 42", + * expression: "this > 42", + * }]; + * } + * ``` + * + * @generated from field: repeated buf.validate.Rule cel = 23; + */ + cel: Rule[]; + + /** + * If `required` is true, the field must be set. A validation error is returned + * if the field is not set. + * + * ```proto + * syntax="proto3"; + * + * message FieldsWithPresence { + * // Requires any string to be set, including the empty string. + * optional string link = 1 [ + * (buf.validate.field).required = true + * ]; + * // Requires true or false to be set. + * optional bool disabled = 2 [ + * (buf.validate.field).required = true + * ]; + * // Requires a message to be set, including the empty message. + * SomeMessage msg = 4 [ + * (buf.validate.field).required = true + * ]; + * } + * ``` + * + * All fields in the example above track presence. By default, Protovalidate + * ignores rules on those fields if no value is set. `required` ensures that + * the fields are set and valid. + * + * Fields that don't track presence are always validated by Protovalidate, + * whether they are set or not. It is not necessary to add `required`. It + * can be added to indicate that the field cannot be the zero value. + * + * ```proto + * syntax="proto3"; + * + * message FieldsWithoutPresence { + * // `string.email` always applies, even to an empty string. + * string link = 1 [ + * (buf.validate.field).string.email = true + * ]; + * // `repeated.min_items` always applies, even to an empty list. + * repeated string labels = 2 [ + * (buf.validate.field).repeated.min_items = 1 + * ]; + * // `required`, for fields that don't track presence, indicates + * // the value of the field can't be the zero value. + * int32 zero_value_not_allowed = 3 [ + * (buf.validate.field).required = true + * ]; + * } + * ``` + * + * To learn which fields track presence, see the + * [Field Presence cheat sheet](https://protobuf.dev/programming-guides/field_presence/#cheat). + * + * Note: While field rules can be applied to repeated items, map keys, and map + * values, the elements are always considered to be set. Consequently, + * specifying `repeated.items.required` is redundant. + * + * @generated from field: optional bool required = 25; + */ + required: boolean; + + /** + * Ignore validation rules on the field if its value matches the specified + * criteria. See the `Ignore` enum for details. + * + * ```proto + * message UpdateRequest { + * // The uri rule only applies if the field is not an empty string. + * string url = 1 [ + * (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE, + * (buf.validate.field).string.uri = true + * ]; + * } + * ``` + * + * @generated from field: optional buf.validate.Ignore ignore = 27; + */ + ignore: Ignore; + + /** + * @generated from oneof buf.validate.FieldRules.type + */ + type: { + /** + * Scalar Field Types + * + * @generated from field: buf.validate.FloatRules float = 1; + */ + value: FloatRules; + case: "float"; + } | { + /** + * @generated from field: buf.validate.DoubleRules double = 2; + */ + value: DoubleRules; + case: "double"; + } | { + /** + * @generated from field: buf.validate.Int32Rules int32 = 3; + */ + value: Int32Rules; + case: "int32"; + } | { + /** + * @generated from field: buf.validate.Int64Rules int64 = 4; + */ + value: Int64Rules; + case: "int64"; + } | { + /** + * @generated from field: buf.validate.UInt32Rules uint32 = 5; + */ + value: UInt32Rules; + case: "uint32"; + } | { + /** + * @generated from field: buf.validate.UInt64Rules uint64 = 6; + */ + value: UInt64Rules; + case: "uint64"; + } | { + /** + * @generated from field: buf.validate.SInt32Rules sint32 = 7; + */ + value: SInt32Rules; + case: "sint32"; + } | { + /** + * @generated from field: buf.validate.SInt64Rules sint64 = 8; + */ + value: SInt64Rules; + case: "sint64"; + } | { + /** + * @generated from field: buf.validate.Fixed32Rules fixed32 = 9; + */ + value: Fixed32Rules; + case: "fixed32"; + } | { + /** + * @generated from field: buf.validate.Fixed64Rules fixed64 = 10; + */ + value: Fixed64Rules; + case: "fixed64"; + } | { + /** + * @generated from field: buf.validate.SFixed32Rules sfixed32 = 11; + */ + value: SFixed32Rules; + case: "sfixed32"; + } | { + /** + * @generated from field: buf.validate.SFixed64Rules sfixed64 = 12; + */ + value: SFixed64Rules; + case: "sfixed64"; + } | { + /** + * @generated from field: buf.validate.BoolRules bool = 13; + */ + value: BoolRules; + case: "bool"; + } | { + /** + * @generated from field: buf.validate.StringRules string = 14; + */ + value: StringRules; + case: "string"; + } | { + /** + * @generated from field: buf.validate.BytesRules bytes = 15; + */ + value: BytesRules; + case: "bytes"; + } | { + /** + * Complex Field Types + * + * @generated from field: buf.validate.EnumRules enum = 16; + */ + value: EnumRules; + case: "enum"; + } | { + /** + * @generated from field: buf.validate.RepeatedRules repeated = 18; + */ + value: RepeatedRules; + case: "repeated"; + } | { + /** + * @generated from field: buf.validate.MapRules map = 19; + */ + value: MapRules; + case: "map"; + } | { + /** + * Well-Known Field Types + * + * @generated from field: buf.validate.AnyRules any = 20; + */ + value: AnyRules; + case: "any"; + } | { + /** + * @generated from field: buf.validate.DurationRules duration = 21; + */ + value: DurationRules; + case: "duration"; + } | { + /** + * @generated from field: buf.validate.FieldMaskRules field_mask = 28; + */ + value: FieldMaskRules; + case: "fieldMask"; + } | { + /** + * @generated from field: buf.validate.TimestampRules timestamp = 22; + */ + value: TimestampRules; + case: "timestamp"; + } | { case: undefined; value?: undefined }; +}; + +/** + * Describes the message buf.validate.FieldRules. + * Use `create(FieldRulesSchema)` to create a new message. + */ +export const FieldRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 4); + +/** + * PredefinedRules are custom rules that can be re-used with + * multiple fields. + * + * @generated from message buf.validate.PredefinedRules + */ +export type PredefinedRules = Message<"buf.validate.PredefinedRules"> & { + /** + * `cel` is a repeated field used to represent a textual expression + * in the Common Expression Language (CEL) syntax. For more information, + * [see our documentation](https://buf.build/docs/protovalidate/schemas/predefined-rules/). + * + * ```proto + * message MyMessage { + * // The field `value` must be greater than 42. + * optional int32 value = 1 [(buf.validate.predefined).cel = { + * id: "my_message.value", + * message: "value must be greater than 42", + * expression: "this > 42", + * }]; + * } + * ``` + * + * @generated from field: repeated buf.validate.Rule cel = 1; + */ + cel: Rule[]; +}; + +/** + * Describes the message buf.validate.PredefinedRules. + * Use `create(PredefinedRulesSchema)` to create a new message. + */ +export const PredefinedRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 5); + +/** + * FloatRules describes the rules applied to `float` values. These + * rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type. + * + * @generated from message buf.validate.FloatRules + */ +export type FloatRules = Message<"buf.validate.FloatRules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyFloat { + * // value must equal 42.0 + * float value = 1 [(buf.validate.field).float.const = 42.0]; + * } + * ``` + * + * @generated from field: optional float const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.FloatRules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyFloat { + * // value must be less than 10.0 + * float value = 1 [(buf.validate.field).float.lt = 10.0]; + * } + * ``` + * + * @generated from field: float lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyFloat { + * // value must be less than or equal to 10.0 + * float value = 1 [(buf.validate.field).float.lte = 10.0]; + * } + * ``` + * + * @generated from field: float lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.FloatRules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFloat { + * // value must be greater than 5.0 [float.gt] + * float value = 1 [(buf.validate.field).float.gt = 5.0]; + * + * // value must be greater than 5 and less than 10.0 [float.gt_lt] + * float other_value = 2 [(buf.validate.field).float = { gt: 5.0, lt: 10.0 }]; + * + * // value must be greater than 10 or less than 5.0 [float.gt_lt_exclusive] + * float another_value = 3 [(buf.validate.field).float = { gt: 10.0, lt: 5.0 }]; + * } + * ``` + * + * @generated from field: float gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFloat { + * // value must be greater than or equal to 5.0 [float.gte] + * float value = 1 [(buf.validate.field).float.gte = 5.0]; + * + * // value must be greater than or equal to 5.0 and less than 10.0 [float.gte_lt] + * float other_value = 2 [(buf.validate.field).float = { gte: 5.0, lt: 10.0 }]; + * + * // value must be greater than or equal to 10.0 or less than 5.0 [float.gte_lt_exclusive] + * float another_value = 3 [(buf.validate.field).float = { gte: 10.0, lt: 5.0 }]; + * } + * ``` + * + * @generated from field: float gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message + * is generated. + * + * ```proto + * message MyFloat { + * // value must be in list [1.0, 2.0, 3.0] + * float value = 1 [(buf.validate.field).float = { in: [1.0, 2.0, 3.0] }]; + * } + * ``` + * + * @generated from field: repeated float in = 6; + */ + in: number[]; + + /** + * `in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyFloat { + * // value must not be in list [1.0, 2.0, 3.0] + * float value = 1 [(buf.validate.field).float = { not_in: [1.0, 2.0, 3.0] }]; + * } + * ``` + * + * @generated from field: repeated float not_in = 7; + */ + notIn: number[]; + + /** + * `finite` requires the field value to be finite. If the field value is + * infinite or NaN, an error message is generated. + * + * @generated from field: optional bool finite = 8; + */ + finite: boolean; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyFloat { + * float value = 1 [ + * (buf.validate.field).float.example = 1.0, + * (buf.validate.field).float.example = inf + * ]; + * } + * ``` + * + * @generated from field: repeated float example = 9; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.FloatRules. + * Use `create(FloatRulesSchema)` to create a new message. + */ +export const FloatRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 6); + +/** + * DoubleRules describes the rules applied to `double` values. These + * rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type. + * + * @generated from message buf.validate.DoubleRules + */ +export type DoubleRules = Message<"buf.validate.DoubleRules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyDouble { + * // value must equal 42.0 + * double value = 1 [(buf.validate.field).double.const = 42.0]; + * } + * ``` + * + * @generated from field: optional double const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.DoubleRules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyDouble { + * // value must be less than 10.0 + * double value = 1 [(buf.validate.field).double.lt = 10.0]; + * } + * ``` + * + * @generated from field: double lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified value + * (field <= value). If the field value is greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyDouble { + * // value must be less than or equal to 10.0 + * double value = 1 [(buf.validate.field).double.lte = 10.0]; + * } + * ``` + * + * @generated from field: double lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.DoubleRules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or `lte`, + * the range is reversed, and the field value must be outside the specified + * range. If the field value doesn't meet the required conditions, an error + * message is generated. + * + * ```proto + * message MyDouble { + * // value must be greater than 5.0 [double.gt] + * double value = 1 [(buf.validate.field).double.gt = 5.0]; + * + * // value must be greater than 5 and less than 10.0 [double.gt_lt] + * double other_value = 2 [(buf.validate.field).double = { gt: 5.0, lt: 10.0 }]; + * + * // value must be greater than 10 or less than 5.0 [double.gt_lt_exclusive] + * double another_value = 3 [(buf.validate.field).double = { gt: 10.0, lt: 5.0 }]; + * } + * ``` + * + * @generated from field: double gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyDouble { + * // value must be greater than or equal to 5.0 [double.gte] + * double value = 1 [(buf.validate.field).double.gte = 5.0]; + * + * // value must be greater than or equal to 5.0 and less than 10.0 [double.gte_lt] + * double other_value = 2 [(buf.validate.field).double = { gte: 5.0, lt: 10.0 }]; + * + * // value must be greater than or equal to 10.0 or less than 5.0 [double.gte_lt_exclusive] + * double another_value = 3 [(buf.validate.field).double = { gte: 10.0, lt: 5.0 }]; + * } + * ``` + * + * @generated from field: double gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyDouble { + * // value must be in list [1.0, 2.0, 3.0] + * double value = 1 [(buf.validate.field).double = { in: [1.0, 2.0, 3.0] }]; + * } + * ``` + * + * @generated from field: repeated double in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyDouble { + * // value must not be in list [1.0, 2.0, 3.0] + * double value = 1 [(buf.validate.field).double = { not_in: [1.0, 2.0, 3.0] }]; + * } + * ``` + * + * @generated from field: repeated double not_in = 7; + */ + notIn: number[]; + + /** + * `finite` requires the field value to be finite. If the field value is + * infinite or NaN, an error message is generated. + * + * @generated from field: optional bool finite = 8; + */ + finite: boolean; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyDouble { + * double value = 1 [ + * (buf.validate.field).double.example = 1.0, + * (buf.validate.field).double.example = inf + * ]; + * } + * ``` + * + * @generated from field: repeated double example = 9; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.DoubleRules. + * Use `create(DoubleRulesSchema)` to create a new message. + */ +export const DoubleRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 7); + +/** + * Int32Rules describes the rules applied to `int32` values. These + * rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type. + * + * @generated from message buf.validate.Int32Rules + */ +export type Int32Rules = Message<"buf.validate.Int32Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyInt32 { + * // value must equal 42 + * int32 value = 1 [(buf.validate.field).int32.const = 42]; + * } + * ``` + * + * @generated from field: optional int32 const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.Int32Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field + * < value). If the field value is equal to or greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyInt32 { + * // value must be less than 10 + * int32 value = 1 [(buf.validate.field).int32.lt = 10]; + * } + * ``` + * + * @generated from field: int32 lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyInt32 { + * // value must be less than or equal to 10 + * int32 value = 1 [(buf.validate.field).int32.lte = 10]; + * } + * ``` + * + * @generated from field: int32 lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.Int32Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyInt32 { + * // value must be greater than 5 [int32.gt] + * int32 value = 1 [(buf.validate.field).int32.gt = 5]; + * + * // value must be greater than 5 and less than 10 [int32.gt_lt] + * int32 other_value = 2 [(buf.validate.field).int32 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [int32.gt_lt_exclusive] + * int32 another_value = 3 [(buf.validate.field).int32 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: int32 gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified value + * (exclusive). If the value of `gte` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyInt32 { + * // value must be greater than or equal to 5 [int32.gte] + * int32 value = 1 [(buf.validate.field).int32.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [int32.gte_lt] + * int32 other_value = 2 [(buf.validate.field).int32 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [int32.gte_lt_exclusive] + * int32 another_value = 3 [(buf.validate.field).int32 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: int32 gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyInt32 { + * // value must be in list [1, 2, 3] + * int32 value = 1 [(buf.validate.field).int32 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated int32 in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error message + * is generated. + * + * ```proto + * message MyInt32 { + * // value must not be in list [1, 2, 3] + * int32 value = 1 [(buf.validate.field).int32 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated int32 not_in = 7; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyInt32 { + * int32 value = 1 [ + * (buf.validate.field).int32.example = 1, + * (buf.validate.field).int32.example = -10 + * ]; + * } + * ``` + * + * @generated from field: repeated int32 example = 8; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.Int32Rules. + * Use `create(Int32RulesSchema)` to create a new message. + */ +export const Int32RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 8); + +/** + * Int64Rules describes the rules applied to `int64` values. These + * rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type. + * + * @generated from message buf.validate.Int64Rules + */ +export type Int64Rules = Message<"buf.validate.Int64Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyInt64 { + * // value must equal 42 + * int64 value = 1 [(buf.validate.field).int64.const = 42]; + * } + * ``` + * + * @generated from field: optional int64 const = 1; + */ + const: bigint; + + /** + * @generated from oneof buf.validate.Int64Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyInt64 { + * // value must be less than 10 + * int64 value = 1 [(buf.validate.field).int64.lt = 10]; + * } + * ``` + * + * @generated from field: int64 lt = 2; + */ + value: bigint; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyInt64 { + * // value must be less than or equal to 10 + * int64 value = 1 [(buf.validate.field).int64.lte = 10]; + * } + * ``` + * + * @generated from field: int64 lte = 3; + */ + value: bigint; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.Int64Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyInt64 { + * // value must be greater than 5 [int64.gt] + * int64 value = 1 [(buf.validate.field).int64.gt = 5]; + * + * // value must be greater than 5 and less than 10 [int64.gt_lt] + * int64 other_value = 2 [(buf.validate.field).int64 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [int64.gt_lt_exclusive] + * int64 another_value = 3 [(buf.validate.field).int64 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: int64 gt = 4; + */ + value: bigint; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyInt64 { + * // value must be greater than or equal to 5 [int64.gte] + * int64 value = 1 [(buf.validate.field).int64.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [int64.gte_lt] + * int64 other_value = 2 [(buf.validate.field).int64 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [int64.gte_lt_exclusive] + * int64 another_value = 3 [(buf.validate.field).int64 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: int64 gte = 5; + */ + value: bigint; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyInt64 { + * // value must be in list [1, 2, 3] + * int64 value = 1 [(buf.validate.field).int64 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated int64 in = 6; + */ + in: bigint[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyInt64 { + * // value must not be in list [1, 2, 3] + * int64 value = 1 [(buf.validate.field).int64 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated int64 not_in = 7; + */ + notIn: bigint[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyInt64 { + * int64 value = 1 [ + * (buf.validate.field).int64.example = 1, + * (buf.validate.field).int64.example = -10 + * ]; + * } + * ``` + * + * @generated from field: repeated int64 example = 9; + */ + example: bigint[]; +}; + +/** + * Describes the message buf.validate.Int64Rules. + * Use `create(Int64RulesSchema)` to create a new message. + */ +export const Int64RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 9); + +/** + * UInt32Rules describes the rules applied to `uint32` values. These + * rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type. + * + * @generated from message buf.validate.UInt32Rules + */ +export type UInt32Rules = Message<"buf.validate.UInt32Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyUInt32 { + * // value must equal 42 + * uint32 value = 1 [(buf.validate.field).uint32.const = 42]; + * } + * ``` + * + * @generated from field: optional uint32 const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.UInt32Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyUInt32 { + * // value must be less than 10 + * uint32 value = 1 [(buf.validate.field).uint32.lt = 10]; + * } + * ``` + * + * @generated from field: uint32 lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyUInt32 { + * // value must be less than or equal to 10 + * uint32 value = 1 [(buf.validate.field).uint32.lte = 10]; + * } + * ``` + * + * @generated from field: uint32 lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.UInt32Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyUInt32 { + * // value must be greater than 5 [uint32.gt] + * uint32 value = 1 [(buf.validate.field).uint32.gt = 5]; + * + * // value must be greater than 5 and less than 10 [uint32.gt_lt] + * uint32 other_value = 2 [(buf.validate.field).uint32 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [uint32.gt_lt_exclusive] + * uint32 another_value = 3 [(buf.validate.field).uint32 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: uint32 gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyUInt32 { + * // value must be greater than or equal to 5 [uint32.gte] + * uint32 value = 1 [(buf.validate.field).uint32.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [uint32.gte_lt] + * uint32 other_value = 2 [(buf.validate.field).uint32 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [uint32.gte_lt_exclusive] + * uint32 another_value = 3 [(buf.validate.field).uint32 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: uint32 gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyUInt32 { + * // value must be in list [1, 2, 3] + * uint32 value = 1 [(buf.validate.field).uint32 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated uint32 in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyUInt32 { + * // value must not be in list [1, 2, 3] + * uint32 value = 1 [(buf.validate.field).uint32 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated uint32 not_in = 7; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyUInt32 { + * uint32 value = 1 [ + * (buf.validate.field).uint32.example = 1, + * (buf.validate.field).uint32.example = 10 + * ]; + * } + * ``` + * + * @generated from field: repeated uint32 example = 8; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.UInt32Rules. + * Use `create(UInt32RulesSchema)` to create a new message. + */ +export const UInt32RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 10); + +/** + * UInt64Rules describes the rules applied to `uint64` values. These + * rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type. + * + * @generated from message buf.validate.UInt64Rules + */ +export type UInt64Rules = Message<"buf.validate.UInt64Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyUInt64 { + * // value must equal 42 + * uint64 value = 1 [(buf.validate.field).uint64.const = 42]; + * } + * ``` + * + * @generated from field: optional uint64 const = 1; + */ + const: bigint; + + /** + * @generated from oneof buf.validate.UInt64Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyUInt64 { + * // value must be less than 10 + * uint64 value = 1 [(buf.validate.field).uint64.lt = 10]; + * } + * ``` + * + * @generated from field: uint64 lt = 2; + */ + value: bigint; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyUInt64 { + * // value must be less than or equal to 10 + * uint64 value = 1 [(buf.validate.field).uint64.lte = 10]; + * } + * ``` + * + * @generated from field: uint64 lte = 3; + */ + value: bigint; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.UInt64Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyUInt64 { + * // value must be greater than 5 [uint64.gt] + * uint64 value = 1 [(buf.validate.field).uint64.gt = 5]; + * + * // value must be greater than 5 and less than 10 [uint64.gt_lt] + * uint64 other_value = 2 [(buf.validate.field).uint64 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [uint64.gt_lt_exclusive] + * uint64 another_value = 3 [(buf.validate.field).uint64 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: uint64 gt = 4; + */ + value: bigint; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyUInt64 { + * // value must be greater than or equal to 5 [uint64.gte] + * uint64 value = 1 [(buf.validate.field).uint64.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [uint64.gte_lt] + * uint64 other_value = 2 [(buf.validate.field).uint64 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [uint64.gte_lt_exclusive] + * uint64 another_value = 3 [(buf.validate.field).uint64 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: uint64 gte = 5; + */ + value: bigint; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyUInt64 { + * // value must be in list [1, 2, 3] + * uint64 value = 1 [(buf.validate.field).uint64 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated uint64 in = 6; + */ + in: bigint[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyUInt64 { + * // value must not be in list [1, 2, 3] + * uint64 value = 1 [(buf.validate.field).uint64 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated uint64 not_in = 7; + */ + notIn: bigint[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyUInt64 { + * uint64 value = 1 [ + * (buf.validate.field).uint64.example = 1, + * (buf.validate.field).uint64.example = -10 + * ]; + * } + * ``` + * + * @generated from field: repeated uint64 example = 8; + */ + example: bigint[]; +}; + +/** + * Describes the message buf.validate.UInt64Rules. + * Use `create(UInt64RulesSchema)` to create a new message. + */ +export const UInt64RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 11); + +/** + * SInt32Rules describes the rules applied to `sint32` values. + * + * @generated from message buf.validate.SInt32Rules + */ +export type SInt32Rules = Message<"buf.validate.SInt32Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MySInt32 { + * // value must equal 42 + * sint32 value = 1 [(buf.validate.field).sint32.const = 42]; + * } + * ``` + * + * @generated from field: optional sint32 const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.SInt32Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field + * < value). If the field value is equal to or greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySInt32 { + * // value must be less than 10 + * sint32 value = 1 [(buf.validate.field).sint32.lt = 10]; + * } + * ``` + * + * @generated from field: sint32 lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySInt32 { + * // value must be less than or equal to 10 + * sint32 value = 1 [(buf.validate.field).sint32.lte = 10]; + * } + * ``` + * + * @generated from field: sint32 lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.SInt32Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySInt32 { + * // value must be greater than 5 [sint32.gt] + * sint32 value = 1 [(buf.validate.field).sint32.gt = 5]; + * + * // value must be greater than 5 and less than 10 [sint32.gt_lt] + * sint32 other_value = 2 [(buf.validate.field).sint32 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [sint32.gt_lt_exclusive] + * sint32 another_value = 3 [(buf.validate.field).sint32 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sint32 gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySInt32 { + * // value must be greater than or equal to 5 [sint32.gte] + * sint32 value = 1 [(buf.validate.field).sint32.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [sint32.gte_lt] + * sint32 other_value = 2 [(buf.validate.field).sint32 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [sint32.gte_lt_exclusive] + * sint32 another_value = 3 [(buf.validate.field).sint32 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sint32 gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MySInt32 { + * // value must be in list [1, 2, 3] + * sint32 value = 1 [(buf.validate.field).sint32 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sint32 in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MySInt32 { + * // value must not be in list [1, 2, 3] + * sint32 value = 1 [(buf.validate.field).sint32 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sint32 not_in = 7; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MySInt32 { + * sint32 value = 1 [ + * (buf.validate.field).sint32.example = 1, + * (buf.validate.field).sint32.example = -10 + * ]; + * } + * ``` + * + * @generated from field: repeated sint32 example = 8; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.SInt32Rules. + * Use `create(SInt32RulesSchema)` to create a new message. + */ +export const SInt32RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 12); + +/** + * SInt64Rules describes the rules applied to `sint64` values. + * + * @generated from message buf.validate.SInt64Rules + */ +export type SInt64Rules = Message<"buf.validate.SInt64Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MySInt64 { + * // value must equal 42 + * sint64 value = 1 [(buf.validate.field).sint64.const = 42]; + * } + * ``` + * + * @generated from field: optional sint64 const = 1; + */ + const: bigint; + + /** + * @generated from oneof buf.validate.SInt64Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field + * < value). If the field value is equal to or greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySInt64 { + * // value must be less than 10 + * sint64 value = 1 [(buf.validate.field).sint64.lt = 10]; + * } + * ``` + * + * @generated from field: sint64 lt = 2; + */ + value: bigint; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySInt64 { + * // value must be less than or equal to 10 + * sint64 value = 1 [(buf.validate.field).sint64.lte = 10]; + * } + * ``` + * + * @generated from field: sint64 lte = 3; + */ + value: bigint; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.SInt64Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySInt64 { + * // value must be greater than 5 [sint64.gt] + * sint64 value = 1 [(buf.validate.field).sint64.gt = 5]; + * + * // value must be greater than 5 and less than 10 [sint64.gt_lt] + * sint64 other_value = 2 [(buf.validate.field).sint64 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [sint64.gt_lt_exclusive] + * sint64 another_value = 3 [(buf.validate.field).sint64 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sint64 gt = 4; + */ + value: bigint; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySInt64 { + * // value must be greater than or equal to 5 [sint64.gte] + * sint64 value = 1 [(buf.validate.field).sint64.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [sint64.gte_lt] + * sint64 other_value = 2 [(buf.validate.field).sint64 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [sint64.gte_lt_exclusive] + * sint64 another_value = 3 [(buf.validate.field).sint64 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sint64 gte = 5; + */ + value: bigint; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message + * is generated. + * + * ```proto + * message MySInt64 { + * // value must be in list [1, 2, 3] + * sint64 value = 1 [(buf.validate.field).sint64 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sint64 in = 6; + */ + in: bigint[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MySInt64 { + * // value must not be in list [1, 2, 3] + * sint64 value = 1 [(buf.validate.field).sint64 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sint64 not_in = 7; + */ + notIn: bigint[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MySInt64 { + * sint64 value = 1 [ + * (buf.validate.field).sint64.example = 1, + * (buf.validate.field).sint64.example = -10 + * ]; + * } + * ``` + * + * @generated from field: repeated sint64 example = 8; + */ + example: bigint[]; +}; + +/** + * Describes the message buf.validate.SInt64Rules. + * Use `create(SInt64RulesSchema)` to create a new message. + */ +export const SInt64RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 13); + +/** + * Fixed32Rules describes the rules applied to `fixed32` values. + * + * @generated from message buf.validate.Fixed32Rules + */ +export type Fixed32Rules = Message<"buf.validate.Fixed32Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. + * If the field value doesn't match, an error message is generated. + * + * ```proto + * message MyFixed32 { + * // value must equal 42 + * fixed32 value = 1 [(buf.validate.field).fixed32.const = 42]; + * } + * ``` + * + * @generated from field: optional fixed32 const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.Fixed32Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyFixed32 { + * // value must be less than 10 + * fixed32 value = 1 [(buf.validate.field).fixed32.lt = 10]; + * } + * ``` + * + * @generated from field: fixed32 lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyFixed32 { + * // value must be less than or equal to 10 + * fixed32 value = 1 [(buf.validate.field).fixed32.lte = 10]; + * } + * ``` + * + * @generated from field: fixed32 lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.Fixed32Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFixed32 { + * // value must be greater than 5 [fixed32.gt] + * fixed32 value = 1 [(buf.validate.field).fixed32.gt = 5]; + * + * // value must be greater than 5 and less than 10 [fixed32.gt_lt] + * fixed32 other_value = 2 [(buf.validate.field).fixed32 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [fixed32.gt_lt_exclusive] + * fixed32 another_value = 3 [(buf.validate.field).fixed32 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: fixed32 gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFixed32 { + * // value must be greater than or equal to 5 [fixed32.gte] + * fixed32 value = 1 [(buf.validate.field).fixed32.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [fixed32.gte_lt] + * fixed32 other_value = 2 [(buf.validate.field).fixed32 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [fixed32.gte_lt_exclusive] + * fixed32 another_value = 3 [(buf.validate.field).fixed32 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: fixed32 gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message + * is generated. + * + * ```proto + * message MyFixed32 { + * // value must be in list [1, 2, 3] + * fixed32 value = 1 [(buf.validate.field).fixed32 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated fixed32 in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyFixed32 { + * // value must not be in list [1, 2, 3] + * fixed32 value = 1 [(buf.validate.field).fixed32 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated fixed32 not_in = 7; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyFixed32 { + * fixed32 value = 1 [ + * (buf.validate.field).fixed32.example = 1, + * (buf.validate.field).fixed32.example = 2 + * ]; + * } + * ``` + * + * @generated from field: repeated fixed32 example = 8; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.Fixed32Rules. + * Use `create(Fixed32RulesSchema)` to create a new message. + */ +export const Fixed32RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 14); + +/** + * Fixed64Rules describes the rules applied to `fixed64` values. + * + * @generated from message buf.validate.Fixed64Rules + */ +export type Fixed64Rules = Message<"buf.validate.Fixed64Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyFixed64 { + * // value must equal 42 + * fixed64 value = 1 [(buf.validate.field).fixed64.const = 42]; + * } + * ``` + * + * @generated from field: optional fixed64 const = 1; + */ + const: bigint; + + /** + * @generated from oneof buf.validate.Fixed64Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MyFixed64 { + * // value must be less than 10 + * fixed64 value = 1 [(buf.validate.field).fixed64.lt = 10]; + * } + * ``` + * + * @generated from field: fixed64 lt = 2; + */ + value: bigint; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MyFixed64 { + * // value must be less than or equal to 10 + * fixed64 value = 1 [(buf.validate.field).fixed64.lte = 10]; + * } + * ``` + * + * @generated from field: fixed64 lte = 3; + */ + value: bigint; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.Fixed64Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFixed64 { + * // value must be greater than 5 [fixed64.gt] + * fixed64 value = 1 [(buf.validate.field).fixed64.gt = 5]; + * + * // value must be greater than 5 and less than 10 [fixed64.gt_lt] + * fixed64 other_value = 2 [(buf.validate.field).fixed64 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [fixed64.gt_lt_exclusive] + * fixed64 another_value = 3 [(buf.validate.field).fixed64 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: fixed64 gt = 4; + */ + value: bigint; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyFixed64 { + * // value must be greater than or equal to 5 [fixed64.gte] + * fixed64 value = 1 [(buf.validate.field).fixed64.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [fixed64.gte_lt] + * fixed64 other_value = 2 [(buf.validate.field).fixed64 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [fixed64.gte_lt_exclusive] + * fixed64 another_value = 3 [(buf.validate.field).fixed64 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: fixed64 gte = 5; + */ + value: bigint; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MyFixed64 { + * // value must be in list [1, 2, 3] + * fixed64 value = 1 [(buf.validate.field).fixed64 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated fixed64 in = 6; + */ + in: bigint[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MyFixed64 { + * // value must not be in list [1, 2, 3] + * fixed64 value = 1 [(buf.validate.field).fixed64 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated fixed64 not_in = 7; + */ + notIn: bigint[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyFixed64 { + * fixed64 value = 1 [ + * (buf.validate.field).fixed64.example = 1, + * (buf.validate.field).fixed64.example = 2 + * ]; + * } + * ``` + * + * @generated from field: repeated fixed64 example = 8; + */ + example: bigint[]; +}; + +/** + * Describes the message buf.validate.Fixed64Rules. + * Use `create(Fixed64RulesSchema)` to create a new message. + */ +export const Fixed64RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 15); + +/** + * SFixed32Rules describes the rules applied to `fixed32` values. + * + * @generated from message buf.validate.SFixed32Rules + */ +export type SFixed32Rules = Message<"buf.validate.SFixed32Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MySFixed32 { + * // value must equal 42 + * sfixed32 value = 1 [(buf.validate.field).sfixed32.const = 42]; + * } + * ``` + * + * @generated from field: optional sfixed32 const = 1; + */ + const: number; + + /** + * @generated from oneof buf.validate.SFixed32Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MySFixed32 { + * // value must be less than 10 + * sfixed32 value = 1 [(buf.validate.field).sfixed32.lt = 10]; + * } + * ``` + * + * @generated from field: sfixed32 lt = 2; + */ + value: number; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySFixed32 { + * // value must be less than or equal to 10 + * sfixed32 value = 1 [(buf.validate.field).sfixed32.lte = 10]; + * } + * ``` + * + * @generated from field: sfixed32 lte = 3; + */ + value: number; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.SFixed32Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySFixed32 { + * // value must be greater than 5 [sfixed32.gt] + * sfixed32 value = 1 [(buf.validate.field).sfixed32.gt = 5]; + * + * // value must be greater than 5 and less than 10 [sfixed32.gt_lt] + * sfixed32 other_value = 2 [(buf.validate.field).sfixed32 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [sfixed32.gt_lt_exclusive] + * sfixed32 another_value = 3 [(buf.validate.field).sfixed32 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sfixed32 gt = 4; + */ + value: number; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySFixed32 { + * // value must be greater than or equal to 5 [sfixed32.gte] + * sfixed32 value = 1 [(buf.validate.field).sfixed32.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [sfixed32.gte_lt] + * sfixed32 other_value = 2 [(buf.validate.field).sfixed32 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [sfixed32.gte_lt_exclusive] + * sfixed32 another_value = 3 [(buf.validate.field).sfixed32 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sfixed32 gte = 5; + */ + value: number; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MySFixed32 { + * // value must be in list [1, 2, 3] + * sfixed32 value = 1 [(buf.validate.field).sfixed32 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sfixed32 in = 6; + */ + in: number[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MySFixed32 { + * // value must not be in list [1, 2, 3] + * sfixed32 value = 1 [(buf.validate.field).sfixed32 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sfixed32 not_in = 7; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MySFixed32 { + * sfixed32 value = 1 [ + * (buf.validate.field).sfixed32.example = 1, + * (buf.validate.field).sfixed32.example = 2 + * ]; + * } + * ``` + * + * @generated from field: repeated sfixed32 example = 8; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.SFixed32Rules. + * Use `create(SFixed32RulesSchema)` to create a new message. + */ +export const SFixed32RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 16); + +/** + * SFixed64Rules describes the rules applied to `fixed64` values. + * + * @generated from message buf.validate.SFixed64Rules + */ +export type SFixed64Rules = Message<"buf.validate.SFixed64Rules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MySFixed64 { + * // value must equal 42 + * sfixed64 value = 1 [(buf.validate.field).sfixed64.const = 42]; + * } + * ``` + * + * @generated from field: optional sfixed64 const = 1; + */ + const: bigint; + + /** + * @generated from oneof buf.validate.SFixed64Rules.less_than + */ + lessThan: { + /** + * `lt` requires the field value to be less than the specified value (field < + * value). If the field value is equal to or greater than the specified value, + * an error message is generated. + * + * ```proto + * message MySFixed64 { + * // value must be less than 10 + * sfixed64 value = 1 [(buf.validate.field).sfixed64.lt = 10]; + * } + * ``` + * + * @generated from field: sfixed64 lt = 2; + */ + value: bigint; + case: "lt"; + } | { + /** + * `lte` requires the field value to be less than or equal to the specified + * value (field <= value). If the field value is greater than the specified + * value, an error message is generated. + * + * ```proto + * message MySFixed64 { + * // value must be less than or equal to 10 + * sfixed64 value = 1 [(buf.validate.field).sfixed64.lte = 10]; + * } + * ``` + * + * @generated from field: sfixed64 lte = 3; + */ + value: bigint; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.SFixed64Rules.greater_than + */ + greaterThan: { + /** + * `gt` requires the field value to be greater than the specified value + * (exclusive). If the value of `gt` is larger than a specified `lt` or + * `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySFixed64 { + * // value must be greater than 5 [sfixed64.gt] + * sfixed64 value = 1 [(buf.validate.field).sfixed64.gt = 5]; + * + * // value must be greater than 5 and less than 10 [sfixed64.gt_lt] + * sfixed64 other_value = 2 [(buf.validate.field).sfixed64 = { gt: 5, lt: 10 }]; + * + * // value must be greater than 10 or less than 5 [sfixed64.gt_lt_exclusive] + * sfixed64 another_value = 3 [(buf.validate.field).sfixed64 = { gt: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sfixed64 gt = 4; + */ + value: bigint; + case: "gt"; + } | { + /** + * `gte` requires the field value to be greater than or equal to the specified + * value (exclusive). If the value of `gte` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MySFixed64 { + * // value must be greater than or equal to 5 [sfixed64.gte] + * sfixed64 value = 1 [(buf.validate.field).sfixed64.gte = 5]; + * + * // value must be greater than or equal to 5 and less than 10 [sfixed64.gte_lt] + * sfixed64 other_value = 2 [(buf.validate.field).sfixed64 = { gte: 5, lt: 10 }]; + * + * // value must be greater than or equal to 10 or less than 5 [sfixed64.gte_lt_exclusive] + * sfixed64 another_value = 3 [(buf.validate.field).sfixed64 = { gte: 10, lt: 5 }]; + * } + * ``` + * + * @generated from field: sfixed64 gte = 5; + */ + value: bigint; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` requires the field value to be equal to one of the specified values. + * If the field value isn't one of the specified values, an error message is + * generated. + * + * ```proto + * message MySFixed64 { + * // value must be in list [1, 2, 3] + * sfixed64 value = 1 [(buf.validate.field).sfixed64 = { in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sfixed64 in = 6; + */ + in: bigint[]; + + /** + * `not_in` requires the field value to not be equal to any of the specified + * values. If the field value is one of the specified values, an error + * message is generated. + * + * ```proto + * message MySFixed64 { + * // value must not be in list [1, 2, 3] + * sfixed64 value = 1 [(buf.validate.field).sfixed64 = { not_in: [1, 2, 3] }]; + * } + * ``` + * + * @generated from field: repeated sfixed64 not_in = 7; + */ + notIn: bigint[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MySFixed64 { + * sfixed64 value = 1 [ + * (buf.validate.field).sfixed64.example = 1, + * (buf.validate.field).sfixed64.example = 2 + * ]; + * } + * ``` + * + * @generated from field: repeated sfixed64 example = 8; + */ + example: bigint[]; +}; + +/** + * Describes the message buf.validate.SFixed64Rules. + * Use `create(SFixed64RulesSchema)` to create a new message. + */ +export const SFixed64RulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 17); + +/** + * BoolRules describes the rules applied to `bool` values. These rules + * may also be applied to the `google.protobuf.BoolValue` Well-Known-Type. + * + * @generated from message buf.validate.BoolRules + */ +export type BoolRules = Message<"buf.validate.BoolRules"> & { + /** + * `const` requires the field value to exactly match the specified boolean value. + * If the field value doesn't match, an error message is generated. + * + * ```proto + * message MyBool { + * // value must equal true + * bool value = 1 [(buf.validate.field).bool.const = true]; + * } + * ``` + * + * @generated from field: optional bool const = 1; + */ + const: boolean; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyBool { + * bool value = 1 [ + * (buf.validate.field).bool.example = 1, + * (buf.validate.field).bool.example = 2 + * ]; + * } + * ``` + * + * @generated from field: repeated bool example = 2; + */ + example: boolean[]; +}; + +/** + * Describes the message buf.validate.BoolRules. + * Use `create(BoolRulesSchema)` to create a new message. + */ +export const BoolRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 18); + +/** + * StringRules describes the rules applied to `string` values These + * rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type. + * + * @generated from message buf.validate.StringRules + */ +export type StringRules = Message<"buf.validate.StringRules"> & { + /** + * `const` requires the field value to exactly match the specified value. If + * the field value doesn't match, an error message is generated. + * + * ```proto + * message MyString { + * // value must equal `hello` + * string value = 1 [(buf.validate.field).string.const = "hello"]; + * } + * ``` + * + * @generated from field: optional string const = 1; + */ + const: string; + + /** + * `len` dictates that the field value must have the specified + * number of characters (Unicode code points), which may differ from the number + * of bytes in the string. If the field value does not meet the specified + * length, an error message will be generated. + * + * ```proto + * message MyString { + * // value length must be 5 characters + * string value = 1 [(buf.validate.field).string.len = 5]; + * } + * ``` + * + * @generated from field: optional uint64 len = 19; + */ + len: bigint; + + /** + * `min_len` specifies that the field value must have at least the specified + * number of characters (Unicode code points), which may differ from the number + * of bytes in the string. If the field value contains fewer characters, an error + * message will be generated. + * + * ```proto + * message MyString { + * // value length must be at least 3 characters + * string value = 1 [(buf.validate.field).string.min_len = 3]; + * } + * ``` + * + * @generated from field: optional uint64 min_len = 2; + */ + minLen: bigint; + + /** + * `max_len` specifies that the field value must have no more than the specified + * number of characters (Unicode code points), which may differ from the + * number of bytes in the string. If the field value contains more characters, + * an error message will be generated. + * + * ```proto + * message MyString { + * // value length must be at most 10 characters + * string value = 1 [(buf.validate.field).string.max_len = 10]; + * } + * ``` + * + * @generated from field: optional uint64 max_len = 3; + */ + maxLen: bigint; + + /** + * `len_bytes` dictates that the field value must have the specified number of + * bytes. If the field value does not match the specified length in bytes, + * an error message will be generated. + * + * ```proto + * message MyString { + * // value length must be 6 bytes + * string value = 1 [(buf.validate.field).string.len_bytes = 6]; + * } + * ``` + * + * @generated from field: optional uint64 len_bytes = 20; + */ + lenBytes: bigint; + + /** + * `min_bytes` specifies that the field value must have at least the specified + * number of bytes. If the field value contains fewer bytes, an error message + * will be generated. + * + * ```proto + * message MyString { + * // value length must be at least 4 bytes + * string value = 1 [(buf.validate.field).string.min_bytes = 4]; + * } + * + * ``` + * + * @generated from field: optional uint64 min_bytes = 4; + */ + minBytes: bigint; + + /** + * `max_bytes` specifies that the field value must have no more than the + * specified number of bytes. If the field value contains more bytes, an + * error message will be generated. + * + * ```proto + * message MyString { + * // value length must be at most 8 bytes + * string value = 1 [(buf.validate.field).string.max_bytes = 8]; + * } + * ``` + * + * @generated from field: optional uint64 max_bytes = 5; + */ + maxBytes: bigint; + + /** + * `pattern` specifies that the field value must match the specified + * regular expression (RE2 syntax), with the expression provided without any + * delimiters. If the field value doesn't match the regular expression, an + * error message will be generated. + * + * ```proto + * message MyString { + * // value does not match regex pattern `^[a-zA-Z]//$` + * string value = 1 [(buf.validate.field).string.pattern = "^[a-zA-Z]//$"]; + * } + * ``` + * + * @generated from field: optional string pattern = 6; + */ + pattern: string; + + /** + * `prefix` specifies that the field value must have the + * specified substring at the beginning of the string. If the field value + * doesn't start with the specified prefix, an error message will be + * generated. + * + * ```proto + * message MyString { + * // value does not have prefix `pre` + * string value = 1 [(buf.validate.field).string.prefix = "pre"]; + * } + * ``` + * + * @generated from field: optional string prefix = 7; + */ + prefix: string; + + /** + * `suffix` specifies that the field value must have the + * specified substring at the end of the string. If the field value doesn't + * end with the specified suffix, an error message will be generated. + * + * ```proto + * message MyString { + * // value does not have suffix `post` + * string value = 1 [(buf.validate.field).string.suffix = "post"]; + * } + * ``` + * + * @generated from field: optional string suffix = 8; + */ + suffix: string; + + /** + * `contains` specifies that the field value must have the + * specified substring anywhere in the string. If the field value doesn't + * contain the specified substring, an error message will be generated. + * + * ```proto + * message MyString { + * // value does not contain substring `inside`. + * string value = 1 [(buf.validate.field).string.contains = "inside"]; + * } + * ``` + * + * @generated from field: optional string contains = 9; + */ + contains: string; + + /** + * `not_contains` specifies that the field value must not have the + * specified substring anywhere in the string. If the field value contains + * the specified substring, an error message will be generated. + * + * ```proto + * message MyString { + * // value contains substring `inside`. + * string value = 1 [(buf.validate.field).string.not_contains = "inside"]; + * } + * ``` + * + * @generated from field: optional string not_contains = 23; + */ + notContains: string; + + /** + * `in` specifies that the field value must be equal to one of the specified + * values. If the field value isn't one of the specified values, an error + * message will be generated. + * + * ```proto + * message MyString { + * // value must be in list ["apple", "banana"] + * string value = 1 [(buf.validate.field).string.in = "apple", (buf.validate.field).string.in = "banana"]; + * } + * ``` + * + * @generated from field: repeated string in = 10; + */ + in: string[]; + + /** + * `not_in` specifies that the field value cannot be equal to any + * of the specified values. If the field value is one of the specified values, + * an error message will be generated. + * ```proto + * message MyString { + * // value must not be in list ["orange", "grape"] + * string value = 1 [(buf.validate.field).string.not_in = "orange", (buf.validate.field).string.not_in = "grape"]; + * } + * ``` + * + * @generated from field: repeated string not_in = 11; + */ + notIn: string[]; + + /** + * `WellKnown` rules provide advanced rules against common string + * patterns. + * + * @generated from oneof buf.validate.StringRules.well_known + */ + wellKnown: { + /** + * `email` specifies that the field value must be a valid email address, for + * example "foo@example.com". + * + * Conforms to the definition for a valid email address from the [HTML standard](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address). + * Note that this standard willfully deviates from [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322), + * which allows many unexpected forms of email addresses and will easily match + * a typographical error. + * + * If the field value isn't a valid email address, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid email address + * string value = 1 [(buf.validate.field).string.email = true]; + * } + * ``` + * + * @generated from field: bool email = 12; + */ + value: boolean; + case: "email"; + } | { + /** + * `hostname` specifies that the field value must be a valid hostname, for + * example "foo.example.com". + * + * A valid hostname follows the rules below: + * - The name consists of one or more labels, separated by a dot ("."). + * - Each label can be 1 to 63 alphanumeric characters. + * - A label can contain hyphens ("-"), but must not start or end with a hyphen. + * - The right-most label must not be digits only. + * - The name can have a trailing dot—for example, "foo.example.com.". + * - The name can be 253 characters at most, excluding the optional trailing dot. + * + * If the field value isn't a valid hostname, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid hostname + * string value = 1 [(buf.validate.field).string.hostname = true]; + * } + * ``` + * + * @generated from field: bool hostname = 13; + */ + value: boolean; + case: "hostname"; + } | { + /** + * `ip` specifies that the field value must be a valid IP (v4 or v6) address. + * + * IPv4 addresses are expected in the dotted decimal format—for example, "192.168.5.21". + * IPv6 addresses are expected in their text representation—for example, "::1", + * or "2001:0DB8:ABCD:0012::0". + * + * Both formats are well-defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). + * Zone identifiers for IPv6 addresses (for example, "fe80::a%en1") are supported. + * + * If the field value isn't a valid IP address, an error message will be + * generated. + * + * ```proto + * message MyString { + * // value must be a valid IP address + * string value = 1 [(buf.validate.field).string.ip = true]; + * } + * ``` + * + * @generated from field: bool ip = 14; + */ + value: boolean; + case: "ip"; + } | { + /** + * `ipv4` specifies that the field value must be a valid IPv4 address—for + * example "192.168.5.21". If the field value isn't a valid IPv4 address, an + * error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv4 address + * string value = 1 [(buf.validate.field).string.ipv4 = true]; + * } + * ``` + * + * @generated from field: bool ipv4 = 15; + */ + value: boolean; + case: "ipv4"; + } | { + /** + * `ipv6` specifies that the field value must be a valid IPv6 address—for + * example "::1", or "d7a:115c:a1e0:ab12:4843:cd96:626b:430b". If the field + * value is not a valid IPv6 address, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv6 address + * string value = 1 [(buf.validate.field).string.ipv6 = true]; + * } + * ``` + * + * @generated from field: bool ipv6 = 16; + */ + value: boolean; + case: "ipv6"; + } | { + /** + * `uri` specifies that the field value must be a valid URI, for example + * "https://example.com/foo/bar?baz=quux#frag". + * + * URI is defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). + * Zone Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)). + * + * If the field value isn't a valid URI, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid URI + * string value = 1 [(buf.validate.field).string.uri = true]; + * } + * ``` + * + * @generated from field: bool uri = 17; + */ + value: boolean; + case: "uri"; + } | { + /** + * `uri_ref` specifies that the field value must be a valid URI Reference—either + * a URI such as "https://example.com/foo/bar?baz=quux#frag", or a Relative + * Reference such as "./foo/bar?query". + * + * URI, URI Reference, and Relative Reference are defined in the internet + * standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). Zone + * Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)). + * + * If the field value isn't a valid URI Reference, an error message will be + * generated. + * + * ```proto + * message MyString { + * // value must be a valid URI Reference + * string value = 1 [(buf.validate.field).string.uri_ref = true]; + * } + * ``` + * + * @generated from field: bool uri_ref = 18; + */ + value: boolean; + case: "uriRef"; + } | { + /** + * `address` specifies that the field value must be either a valid hostname + * (for example, "example.com"), or a valid IP (v4 or v6) address (for example, + * "192.168.0.1", or "::1"). If the field value isn't a valid hostname or IP, + * an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid hostname, or ip address + * string value = 1 [(buf.validate.field).string.address = true]; + * } + * ``` + * + * @generated from field: bool address = 21; + */ + value: boolean; + case: "address"; + } | { + /** + * `uuid` specifies that the field value must be a valid UUID as defined by + * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.2). If the + * field value isn't a valid UUID, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid UUID + * string value = 1 [(buf.validate.field).string.uuid = true]; + * } + * ``` + * + * @generated from field: bool uuid = 22; + */ + value: boolean; + case: "uuid"; + } | { + /** + * `tuuid` (trimmed UUID) specifies that the field value must be a valid UUID as + * defined by [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.2) with all dashes + * omitted. If the field value isn't a valid UUID without dashes, an error message + * will be generated. + * + * ```proto + * message MyString { + * // value must be a valid trimmed UUID + * string value = 1 [(buf.validate.field).string.tuuid = true]; + * } + * ``` + * + * @generated from field: bool tuuid = 33; + */ + value: boolean; + case: "tuuid"; + } | { + /** + * `ip_with_prefixlen` specifies that the field value must be a valid IP + * (v4 or v6) address with prefix length—for example, "192.168.5.21/16" or + * "2001:0DB8:ABCD:0012::F1/64". If the field value isn't a valid IP with + * prefix length, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IP with prefix length + * string value = 1 [(buf.validate.field).string.ip_with_prefixlen = true]; + * } + * ``` + * + * @generated from field: bool ip_with_prefixlen = 26; + */ + value: boolean; + case: "ipWithPrefixlen"; + } | { + /** + * `ipv4_with_prefixlen` specifies that the field value must be a valid + * IPv4 address with prefix length—for example, "192.168.5.21/16". If the + * field value isn't a valid IPv4 address with prefix length, an error + * message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv4 address with prefix length + * string value = 1 [(buf.validate.field).string.ipv4_with_prefixlen = true]; + * } + * ``` + * + * @generated from field: bool ipv4_with_prefixlen = 27; + */ + value: boolean; + case: "ipv4WithPrefixlen"; + } | { + /** + * `ipv6_with_prefixlen` specifies that the field value must be a valid + * IPv6 address with prefix length—for example, "2001:0DB8:ABCD:0012::F1/64". + * If the field value is not a valid IPv6 address with prefix length, + * an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv6 address prefix length + * string value = 1 [(buf.validate.field).string.ipv6_with_prefixlen = true]; + * } + * ``` + * + * @generated from field: bool ipv6_with_prefixlen = 28; + */ + value: boolean; + case: "ipv6WithPrefixlen"; + } | { + /** + * `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) + * prefix—for example, "192.168.0.0/16" or "2001:0DB8:ABCD:0012::0/64". + * + * The prefix must have all zeros for the unmasked bits. For example, + * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the + * prefix, and the remaining 64 bits must be zero. + * + * If the field value isn't a valid IP prefix, an error message will be + * generated. + * + * ```proto + * message MyString { + * // value must be a valid IP prefix + * string value = 1 [(buf.validate.field).string.ip_prefix = true]; + * } + * ``` + * + * @generated from field: bool ip_prefix = 29; + */ + value: boolean; + case: "ipPrefix"; + } | { + /** + * `ipv4_prefix` specifies that the field value must be a valid IPv4 + * prefix, for example "192.168.0.0/16". + * + * The prefix must have all zeros for the unmasked bits. For example, + * "192.168.0.0/16" designates the left-most 16 bits for the prefix, + * and the remaining 16 bits must be zero. + * + * If the field value isn't a valid IPv4 prefix, an error message + * will be generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv4 prefix + * string value = 1 [(buf.validate.field).string.ipv4_prefix = true]; + * } + * ``` + * + * @generated from field: bool ipv4_prefix = 30; + */ + value: boolean; + case: "ipv4Prefix"; + } | { + /** + * `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix—for + * example, "2001:0DB8:ABCD:0012::0/64". + * + * The prefix must have all zeros for the unmasked bits. For example, + * "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the + * prefix, and the remaining 64 bits must be zero. + * + * If the field value is not a valid IPv6 prefix, an error message will be + * generated. + * + * ```proto + * message MyString { + * // value must be a valid IPv6 prefix + * string value = 1 [(buf.validate.field).string.ipv6_prefix = true]; + * } + * ``` + * + * @generated from field: bool ipv6_prefix = 31; + */ + value: boolean; + case: "ipv6Prefix"; + } | { + /** + * `host_and_port` specifies that the field value must be valid host/port + * pair—for example, "example.com:8080". + * + * The host can be one of: + * - An IPv4 address in dotted decimal format—for example, "192.168.5.21". + * - An IPv6 address enclosed in square brackets—for example, "[2001:0DB8:ABCD:0012::F1]". + * - A hostname—for example, "example.com". + * + * The port is separated by a colon. It must be non-empty, with a decimal number + * in the range of 0-65535, inclusive. + * + * @generated from field: bool host_and_port = 32; + */ + value: boolean; + case: "hostAndPort"; + } | { + /** + * `ulid` specifies that the field value must be a valid ULID (Universally Unique + * Lexicographically Sortable Identifier) as defined by the [ULID specification](https://github.com/ulid/spec). + * If the field value isn't a valid ULID, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid ULID + * string value = 1 [(buf.validate.field).string.ulid = true]; + * } + * ``` + * + * @generated from field: bool ulid = 35; + */ + value: boolean; + case: "ulid"; + } | { + /** + * `well_known_regex` specifies a common well-known pattern + * defined as a regex. If the field value doesn't match the well-known + * regex, an error message will be generated. + * + * ```proto + * message MyString { + * // value must be a valid HTTP header value + * string value = 1 [(buf.validate.field).string.well_known_regex = KNOWN_REGEX_HTTP_HEADER_VALUE]; + * } + * ``` + * + * #### KnownRegex + * + * `well_known_regex` contains some well-known patterns. + * + * | Name | Number | Description | + * |-------------------------------|--------|-------------------------------------------| + * | KNOWN_REGEX_UNSPECIFIED | 0 | | + * | KNOWN_REGEX_HTTP_HEADER_NAME | 1 | HTTP header name as defined by [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2) | + * | KNOWN_REGEX_HTTP_HEADER_VALUE | 2 | HTTP header value as defined by [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4) | + * + * @generated from field: buf.validate.KnownRegex well_known_regex = 24; + */ + value: KnownRegex; + case: "wellKnownRegex"; + } | { case: undefined; value?: undefined }; + + /** + * This applies to regexes `HTTP_HEADER_NAME` and `HTTP_HEADER_VALUE` to + * enable strict header validation. By default, this is true, and HTTP header + * validations are [RFC-compliant](https://datatracker.ietf.org/doc/html/rfc7230#section-3). Setting to false will enable looser + * validations that only disallow `\r\n\0` characters, which can be used to + * bypass header matching rules. + * + * ```proto + * message MyString { + * // The field `value` must have be a valid HTTP headers, but not enforced with strict rules. + * string value = 1 [(buf.validate.field).string.strict = false]; + * } + * ``` + * + * @generated from field: optional bool strict = 25; + */ + strict: boolean; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyString { + * string value = 1 [ + * (buf.validate.field).string.example = "hello", + * (buf.validate.field).string.example = "world" + * ]; + * } + * ``` + * + * @generated from field: repeated string example = 34; + */ + example: string[]; +}; + +/** + * Describes the message buf.validate.StringRules. + * Use `create(StringRulesSchema)` to create a new message. + */ +export const StringRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 19); + +/** + * BytesRules describe the rules applied to `bytes` values. These rules + * may also be applied to the `google.protobuf.BytesValue` Well-Known-Type. + * + * @generated from message buf.validate.BytesRules + */ +export type BytesRules = Message<"buf.validate.BytesRules"> & { + /** + * `const` requires the field value to exactly match the specified bytes + * value. If the field value doesn't match, an error message is generated. + * + * ```proto + * message MyBytes { + * // value must be "\x01\x02\x03\x04" + * bytes value = 1 [(buf.validate.field).bytes.const = "\x01\x02\x03\x04"]; + * } + * ``` + * + * @generated from field: optional bytes const = 1; + */ + const: Uint8Array; + + /** + * `len` requires the field value to have the specified length in bytes. + * If the field value doesn't match, an error message is generated. + * + * ```proto + * message MyBytes { + * // value length must be 4 bytes. + * optional bytes value = 1 [(buf.validate.field).bytes.len = 4]; + * } + * ``` + * + * @generated from field: optional uint64 len = 13; + */ + len: bigint; + + /** + * `min_len` requires the field value to have at least the specified minimum + * length in bytes. + * If the field value doesn't meet the requirement, an error message is generated. + * + * ```proto + * message MyBytes { + * // value length must be at least 2 bytes. + * optional bytes value = 1 [(buf.validate.field).bytes.min_len = 2]; + * } + * ``` + * + * @generated from field: optional uint64 min_len = 2; + */ + minLen: bigint; + + /** + * `max_len` requires the field value to have at most the specified maximum + * length in bytes. + * If the field value exceeds the requirement, an error message is generated. + * + * ```proto + * message MyBytes { + * // value must be at most 6 bytes. + * optional bytes value = 1 [(buf.validate.field).bytes.max_len = 6]; + * } + * ``` + * + * @generated from field: optional uint64 max_len = 3; + */ + maxLen: bigint; + + /** + * `pattern` requires the field value to match the specified regular + * expression ([RE2 syntax](https://github.com/google/re2/wiki/Syntax)). + * The value of the field must be valid UTF-8 or validation will fail with a + * runtime error. + * If the field value doesn't match the pattern, an error message is generated. + * + * ```proto + * message MyBytes { + * // value must match regex pattern "^[a-zA-Z0-9]+$". + * optional bytes value = 1 [(buf.validate.field).bytes.pattern = "^[a-zA-Z0-9]+$"]; + * } + * ``` + * + * @generated from field: optional string pattern = 4; + */ + pattern: string; + + /** + * `prefix` requires the field value to have the specified bytes at the + * beginning of the string. + * If the field value doesn't meet the requirement, an error message is generated. + * + * ```proto + * message MyBytes { + * // value does not have prefix \x01\x02 + * optional bytes value = 1 [(buf.validate.field).bytes.prefix = "\x01\x02"]; + * } + * ``` + * + * @generated from field: optional bytes prefix = 5; + */ + prefix: Uint8Array; + + /** + * `suffix` requires the field value to have the specified bytes at the end + * of the string. + * If the field value doesn't meet the requirement, an error message is generated. + * + * ```proto + * message MyBytes { + * // value does not have suffix \x03\x04 + * optional bytes value = 1 [(buf.validate.field).bytes.suffix = "\x03\x04"]; + * } + * ``` + * + * @generated from field: optional bytes suffix = 6; + */ + suffix: Uint8Array; + + /** + * `contains` requires the field value to have the specified bytes anywhere in + * the string. + * If the field value doesn't meet the requirement, an error message is generated. + * + * ```proto + * message MyBytes { + * // value does not contain \x02\x03 + * optional bytes value = 1 [(buf.validate.field).bytes.contains = "\x02\x03"]; + * } + * ``` + * + * @generated from field: optional bytes contains = 7; + */ + contains: Uint8Array; + + /** + * `in` requires the field value to be equal to one of the specified + * values. If the field value doesn't match any of the specified values, an + * error message is generated. + * + * ```proto + * message MyBytes { + * // value must in ["\x01\x02", "\x02\x03", "\x03\x04"] + * optional bytes value = 1 [(buf.validate.field).bytes.in = {"\x01\x02", "\x02\x03", "\x03\x04"}]; + * } + * ``` + * + * @generated from field: repeated bytes in = 8; + */ + in: Uint8Array[]; + + /** + * `not_in` requires the field value to be not equal to any of the specified + * values. + * If the field value matches any of the specified values, an error message is + * generated. + * + * ```proto + * message MyBytes { + * // value must not in ["\x01\x02", "\x02\x03", "\x03\x04"] + * optional bytes value = 1 [(buf.validate.field).bytes.not_in = {"\x01\x02", "\x02\x03", "\x03\x04"}]; + * } + * ``` + * + * @generated from field: repeated bytes not_in = 9; + */ + notIn: Uint8Array[]; + + /** + * WellKnown rules provide advanced rules against common byte + * patterns + * + * @generated from oneof buf.validate.BytesRules.well_known + */ + wellKnown: { + /** + * `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format. + * If the field value doesn't meet this rule, an error message is generated. + * + * ```proto + * message MyBytes { + * // value must be a valid IP address + * optional bytes value = 1 [(buf.validate.field).bytes.ip = true]; + * } + * ``` + * + * @generated from field: bool ip = 10; + */ + value: boolean; + case: "ip"; + } | { + /** + * `ipv4` ensures that the field `value` is a valid IPv4 address in byte format. + * If the field value doesn't meet this rule, an error message is generated. + * + * ```proto + * message MyBytes { + * // value must be a valid IPv4 address + * optional bytes value = 1 [(buf.validate.field).bytes.ipv4 = true]; + * } + * ``` + * + * @generated from field: bool ipv4 = 11; + */ + value: boolean; + case: "ipv4"; + } | { + /** + * `ipv6` ensures that the field `value` is a valid IPv6 address in byte format. + * If the field value doesn't meet this rule, an error message is generated. + * ```proto + * message MyBytes { + * // value must be a valid IPv6 address + * optional bytes value = 1 [(buf.validate.field).bytes.ipv6 = true]; + * } + * ``` + * + * @generated from field: bool ipv6 = 12; + */ + value: boolean; + case: "ipv6"; + } | { + /** + * `uuid` ensures that the field `value` encodes the 128-bit UUID data as + * defined by [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.2). + * The field must contain exactly 16 bytes + * representing the UUID. If the field value isn't a valid UUID, an error + * message will be generated. + * + * ```proto + * message MyBytes { + * // value must be a valid UUID + * optional bytes value = 1 [(buf.validate.field).bytes.uuid = true]; + * } + * ``` + * + * @generated from field: bool uuid = 15; + */ + value: boolean; + case: "uuid"; + } | { case: undefined; value?: undefined }; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyBytes { + * bytes value = 1 [ + * (buf.validate.field).bytes.example = "\x01\x02", + * (buf.validate.field).bytes.example = "\x02\x03" + * ]; + * } + * ``` + * + * @generated from field: repeated bytes example = 14; + */ + example: Uint8Array[]; +}; + +/** + * Describes the message buf.validate.BytesRules. + * Use `create(BytesRulesSchema)` to create a new message. + */ +export const BytesRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 20); + +/** + * EnumRules describe the rules applied to `enum` values. + * + * @generated from message buf.validate.EnumRules + */ +export type EnumRules = Message<"buf.validate.EnumRules"> & { + /** + * `const` requires the field value to exactly match the specified enum value. + * If the field value doesn't match, an error message is generated. + * + * ```proto + * enum MyEnum { + * MY_ENUM_UNSPECIFIED = 0; + * MY_ENUM_VALUE1 = 1; + * MY_ENUM_VALUE2 = 2; + * } + * + * message MyMessage { + * // The field `value` must be exactly MY_ENUM_VALUE1. + * MyEnum value = 1 [(buf.validate.field).enum.const = 1]; + * } + * ``` + * + * @generated from field: optional int32 const = 1; + */ + const: number; + + /** + * `defined_only` requires the field value to be one of the defined values for + * this enum, failing on any undefined value. + * + * ```proto + * enum MyEnum { + * MY_ENUM_UNSPECIFIED = 0; + * MY_ENUM_VALUE1 = 1; + * MY_ENUM_VALUE2 = 2; + * } + * + * message MyMessage { + * // The field `value` must be a defined value of MyEnum. + * MyEnum value = 1 [(buf.validate.field).enum.defined_only = true]; + * } + * ``` + * + * @generated from field: optional bool defined_only = 2; + */ + definedOnly: boolean; + + /** + * `in` requires the field value to be equal to one of the + * specified enum values. If the field value doesn't match any of the + * specified values, an error message is generated. + * + * ```proto + * enum MyEnum { + * MY_ENUM_UNSPECIFIED = 0; + * MY_ENUM_VALUE1 = 1; + * MY_ENUM_VALUE2 = 2; + * } + * + * message MyMessage { + * // The field `value` must be equal to one of the specified values. + * MyEnum value = 1 [(buf.validate.field).enum = { in: [1, 2]}]; + * } + * ``` + * + * @generated from field: repeated int32 in = 3; + */ + in: number[]; + + /** + * `not_in` requires the field value to be not equal to any of the + * specified enum values. If the field value matches one of the specified + * values, an error message is generated. + * + * ```proto + * enum MyEnum { + * MY_ENUM_UNSPECIFIED = 0; + * MY_ENUM_VALUE1 = 1; + * MY_ENUM_VALUE2 = 2; + * } + * + * message MyMessage { + * // The field `value` must not be equal to any of the specified values. + * MyEnum value = 1 [(buf.validate.field).enum = { not_in: [1, 2]}]; + * } + * ``` + * + * @generated from field: repeated int32 not_in = 4; + */ + notIn: number[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * enum MyEnum { + * MY_ENUM_UNSPECIFIED = 0; + * MY_ENUM_VALUE1 = 1; + * MY_ENUM_VALUE2 = 2; + * } + * + * message MyMessage { + * (buf.validate.field).enum.example = 1, + * (buf.validate.field).enum.example = 2 + * } + * ``` + * + * @generated from field: repeated int32 example = 5; + */ + example: number[]; +}; + +/** + * Describes the message buf.validate.EnumRules. + * Use `create(EnumRulesSchema)` to create a new message. + */ +export const EnumRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 21); + +/** + * RepeatedRules describe the rules applied to `repeated` values. + * + * @generated from message buf.validate.RepeatedRules + */ +export type RepeatedRules = Message<"buf.validate.RepeatedRules"> & { + /** + * `min_items` requires that this field must contain at least the specified + * minimum number of items. + * + * Note that `min_items = 1` is equivalent to setting a field as `required`. + * + * ```proto + * message MyRepeated { + * // value must contain at least 2 items + * repeated string value = 1 [(buf.validate.field).repeated.min_items = 2]; + * } + * ``` + * + * @generated from field: optional uint64 min_items = 1; + */ + minItems: bigint; + + /** + * `max_items` denotes that this field must not exceed a + * certain number of items as the upper limit. If the field contains more + * items than specified, an error message will be generated, requiring the + * field to maintain no more than the specified number of items. + * + * ```proto + * message MyRepeated { + * // value must contain no more than 3 item(s) + * repeated string value = 1 [(buf.validate.field).repeated.max_items = 3]; + * } + * ``` + * + * @generated from field: optional uint64 max_items = 2; + */ + maxItems: bigint; + + /** + * `unique` indicates that all elements in this field must + * be unique. This rule is strictly applicable to scalar and enum + * types, with message types not being supported. + * + * ```proto + * message MyRepeated { + * // repeated value must contain unique items + * repeated string value = 1 [(buf.validate.field).repeated.unique = true]; + * } + * ``` + * + * @generated from field: optional bool unique = 3; + */ + unique: boolean; + + /** + * `items` details the rules to be applied to each item + * in the field. Even for repeated message fields, validation is executed + * against each item unless `ignore` is specified. + * + * ```proto + * message MyRepeated { + * // The items in the field `value` must follow the specified rules. + * repeated string value = 1 [(buf.validate.field).repeated.items = { + * string: { + * min_len: 3 + * max_len: 10 + * } + * }]; + * } + * ``` + * + * Note that the `required` rule does not apply. Repeated items + * cannot be unset. + * + * @generated from field: optional buf.validate.FieldRules items = 4; + */ + items?: FieldRules; +}; + +/** + * Describes the message buf.validate.RepeatedRules. + * Use `create(RepeatedRulesSchema)` to create a new message. + */ +export const RepeatedRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 22); + +/** + * MapRules describe the rules applied to `map` values. + * + * @generated from message buf.validate.MapRules + */ +export type MapRules = Message<"buf.validate.MapRules"> & { + /** + * Specifies the minimum number of key-value pairs allowed. If the field has + * fewer key-value pairs than specified, an error message is generated. + * + * ```proto + * message MyMap { + * // The field `value` must have at least 2 key-value pairs. + * map value = 1 [(buf.validate.field).map.min_pairs = 2]; + * } + * ``` + * + * @generated from field: optional uint64 min_pairs = 1; + */ + minPairs: bigint; + + /** + * Specifies the maximum number of key-value pairs allowed. If the field has + * more key-value pairs than specified, an error message is generated. + * + * ```proto + * message MyMap { + * // The field `value` must have at most 3 key-value pairs. + * map value = 1 [(buf.validate.field).map.max_pairs = 3]; + * } + * ``` + * + * @generated from field: optional uint64 max_pairs = 2; + */ + maxPairs: bigint; + + /** + * Specifies the rules to be applied to each key in the field. + * + * ```proto + * message MyMap { + * // The keys in the field `value` must follow the specified rules. + * map value = 1 [(buf.validate.field).map.keys = { + * string: { + * min_len: 3 + * max_len: 10 + * } + * }]; + * } + * ``` + * + * Note that the `required` rule does not apply. Map keys cannot be unset. + * + * @generated from field: optional buf.validate.FieldRules keys = 4; + */ + keys?: FieldRules; + + /** + * Specifies the rules to be applied to the value of each key in the + * field. Message values will still have their validations evaluated unless + * `ignore` is specified. + * + * ```proto + * message MyMap { + * // The values in the field `value` must follow the specified rules. + * map value = 1 [(buf.validate.field).map.values = { + * string: { + * min_len: 5 + * max_len: 20 + * } + * }]; + * } + * ``` + * Note that the `required` rule does not apply. Map values cannot be unset. + * + * @generated from field: optional buf.validate.FieldRules values = 5; + */ + values?: FieldRules; +}; + +/** + * Describes the message buf.validate.MapRules. + * Use `create(MapRulesSchema)` to create a new message. + */ +export const MapRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 23); + +/** + * AnyRules describe rules applied exclusively to the `google.protobuf.Any` well-known type. + * + * @generated from message buf.validate.AnyRules + */ +export type AnyRules = Message<"buf.validate.AnyRules"> & { + /** + * `in` requires the field's `type_url` to be equal to one of the + * specified values. If it doesn't match any of the specified values, an error + * message is generated. + * + * ```proto + * message MyAny { + * // The `value` field must have a `type_url` equal to one of the specified values. + * google.protobuf.Any value = 1 [(buf.validate.field).any = { + * in: ["type.googleapis.com/MyType1", "type.googleapis.com/MyType2"] + * }]; + * } + * ``` + * + * @generated from field: repeated string in = 2; + */ + in: string[]; + + /** + * requires the field's type_url to be not equal to any of the specified values. If it matches any of the specified values, an error message is generated. + * + * ```proto + * message MyAny { + * // The `value` field must not have a `type_url` equal to any of the specified values. + * google.protobuf.Any value = 1 [(buf.validate.field).any = { + * not_in: ["type.googleapis.com/ForbiddenType1", "type.googleapis.com/ForbiddenType2"] + * }]; + * } + * ``` + * + * @generated from field: repeated string not_in = 3; + */ + notIn: string[]; +}; + +/** + * Describes the message buf.validate.AnyRules. + * Use `create(AnyRulesSchema)` to create a new message. + */ +export const AnyRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 24); + +/** + * DurationRules describe the rules applied exclusively to the `google.protobuf.Duration` well-known type. + * + * @generated from message buf.validate.DurationRules + */ +export type DurationRules = Message<"buf.validate.DurationRules"> & { + /** + * `const` dictates that the field must match the specified value of the `google.protobuf.Duration` type exactly. + * If the field's value deviates from the specified value, an error message + * will be generated. + * + * ```proto + * message MyDuration { + * // value must equal 5s + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.const = "5s"]; + * } + * ``` + * + * @generated from field: optional google.protobuf.Duration const = 2; + */ + const?: Duration; + + /** + * @generated from oneof buf.validate.DurationRules.less_than + */ + lessThan: { + /** + * `lt` stipulates that the field must be less than the specified value of the `google.protobuf.Duration` type, + * exclusive. If the field's value is greater than or equal to the specified + * value, an error message will be generated. + * + * ```proto + * message MyDuration { + * // value must be less than 5s + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = "5s"]; + * } + * ``` + * + * @generated from field: google.protobuf.Duration lt = 3; + */ + value: Duration; + case: "lt"; + } | { + /** + * `lte` indicates that the field must be less than or equal to the specified + * value of the `google.protobuf.Duration` type, inclusive. If the field's value is greater than the specified value, + * an error message will be generated. + * + * ```proto + * message MyDuration { + * // value must be less than or equal to 10s + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.lte = "10s"]; + * } + * ``` + * + * @generated from field: google.protobuf.Duration lte = 4; + */ + value: Duration; + case: "lte"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.DurationRules.greater_than + */ + greaterThan: { + /** + * `gt` requires the duration field value to be greater than the specified + * value (exclusive). If the value of `gt` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyDuration { + * // duration must be greater than 5s [duration.gt] + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.gt = { seconds: 5 }]; + * + * // duration must be greater than 5s and less than 10s [duration.gt_lt] + * google.protobuf.Duration another_value = 2 [(buf.validate.field).duration = { gt: { seconds: 5 }, lt: { seconds: 10 } }]; + * + * // duration must be greater than 10s or less than 5s [duration.gt_lt_exclusive] + * google.protobuf.Duration other_value = 3 [(buf.validate.field).duration = { gt: { seconds: 10 }, lt: { seconds: 5 } }]; + * } + * ``` + * + * @generated from field: google.protobuf.Duration gt = 5; + */ + value: Duration; + case: "gt"; + } | { + /** + * `gte` requires the duration field value to be greater than or equal to the + * specified value (exclusive). If the value of `gte` is larger than a + * specified `lt` or `lte`, the range is reversed, and the field value must + * be outside the specified range. If the field value doesn't meet the + * required conditions, an error message is generated. + * + * ```proto + * message MyDuration { + * // duration must be greater than or equal to 5s [duration.gte] + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.gte = { seconds: 5 }]; + * + * // duration must be greater than or equal to 5s and less than 10s [duration.gte_lt] + * google.protobuf.Duration another_value = 2 [(buf.validate.field).duration = { gte: { seconds: 5 }, lt: { seconds: 10 } }]; + * + * // duration must be greater than or equal to 10s or less than 5s [duration.gte_lt_exclusive] + * google.protobuf.Duration other_value = 3 [(buf.validate.field).duration = { gte: { seconds: 10 }, lt: { seconds: 5 } }]; + * } + * ``` + * + * @generated from field: google.protobuf.Duration gte = 6; + */ + value: Duration; + case: "gte"; + } | { case: undefined; value?: undefined }; + + /** + * `in` asserts that the field must be equal to one of the specified values of the `google.protobuf.Duration` type. + * If the field's value doesn't correspond to any of the specified values, + * an error message will be generated. + * + * ```proto + * message MyDuration { + * // value must be in list [1s, 2s, 3s] + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.in = ["1s", "2s", "3s"]]; + * } + * ``` + * + * @generated from field: repeated google.protobuf.Duration in = 7; + */ + in: Duration[]; + + /** + * `not_in` denotes that the field must not be equal to + * any of the specified values of the `google.protobuf.Duration` type. + * If the field's value matches any of these values, an error message will be + * generated. + * + * ```proto + * message MyDuration { + * // value must not be in list [1s, 2s, 3s] + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.not_in = ["1s", "2s", "3s"]]; + * } + * ``` + * + * @generated from field: repeated google.protobuf.Duration not_in = 8; + */ + notIn: Duration[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyDuration { + * google.protobuf.Duration value = 1 [ + * (buf.validate.field).duration.example = { seconds: 1 }, + * (buf.validate.field).duration.example = { seconds: 2 }, + * ]; + * } + * ``` + * + * @generated from field: repeated google.protobuf.Duration example = 9; + */ + example: Duration[]; +}; + +/** + * Describes the message buf.validate.DurationRules. + * Use `create(DurationRulesSchema)` to create a new message. + */ +export const DurationRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 25); + +/** + * FieldMaskRules describe rules applied exclusively to the `google.protobuf.FieldMask` well-known type. + * + * @generated from message buf.validate.FieldMaskRules + */ +export type FieldMaskRules = Message<"buf.validate.FieldMaskRules"> & { + /** + * `const` dictates that the field must match the specified value of the `google.protobuf.FieldMask` type exactly. + * If the field's value deviates from the specified value, an error message + * will be generated. + * + * ```proto + * message MyFieldMask { + * // value must equal ["a"] + * google.protobuf.FieldMask value = 1 [(buf.validate.field).field_mask.const = { + * paths: ["a"] + * }]; + * } + * ``` + * + * @generated from field: optional google.protobuf.FieldMask const = 1; + */ + const?: FieldMask; + + /** + * `in` requires the field value to only contain paths matching specified + * values or their subpaths. + * If any of the field value's paths doesn't match the rule, + * an error message is generated. + * See: https://protobuf.dev/reference/protobuf/google.protobuf/#field-mask + * + * ```proto + * message MyFieldMask { + * // The `value` FieldMask must only contain paths listed in `in`. + * google.protobuf.FieldMask value = 1 [(buf.validate.field).field_mask = { + * in: ["a", "b", "c.a"] + * }]; + * } + * ``` + * + * @generated from field: repeated string in = 2; + */ + in: string[]; + + /** + * `not_in` requires the field value to not contain paths matching specified + * values or their subpaths. + * If any of the field value's paths matches the rule, + * an error message is generated. + * See: https://protobuf.dev/reference/protobuf/google.protobuf/#field-mask + * + * ```proto + * message MyFieldMask { + * // The `value` FieldMask shall not contain paths listed in `not_in`. + * google.protobuf.FieldMask value = 1 [(buf.validate.field).field_mask = { + * not_in: ["forbidden", "immutable", "c.a"] + * }]; + * } + * ``` + * + * @generated from field: repeated string not_in = 3; + */ + notIn: string[]; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyFieldMask { + * google.protobuf.FieldMask value = 1 [ + * (buf.validate.field).field_mask.example = { paths: ["a", "b"] }, + * (buf.validate.field).field_mask.example = { paths: ["c.a", "d"] }, + * ]; + * } + * ``` + * + * @generated from field: repeated google.protobuf.FieldMask example = 4; + */ + example: FieldMask[]; +}; + +/** + * Describes the message buf.validate.FieldMaskRules. + * Use `create(FieldMaskRulesSchema)` to create a new message. + */ +export const FieldMaskRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 26); + +/** + * TimestampRules describe the rules applied exclusively to the `google.protobuf.Timestamp` well-known type. + * + * @generated from message buf.validate.TimestampRules + */ +export type TimestampRules = Message<"buf.validate.TimestampRules"> & { + /** + * `const` dictates that this field, of the `google.protobuf.Timestamp` type, must exactly match the specified value. If the field value doesn't correspond to the specified timestamp, an error message will be generated. + * + * ```proto + * message MyTimestamp { + * // value must equal 2023-05-03T10:00:00Z + * google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.const = {seconds: 1727998800}]; + * } + * ``` + * + * @generated from field: optional google.protobuf.Timestamp const = 2; + */ + const?: Timestamp; + + /** + * @generated from oneof buf.validate.TimestampRules.less_than + */ + lessThan: { + /** + * requires the duration field value to be less than the specified value (field < value). If the field value doesn't meet the required conditions, an error message is generated. + * + * ```proto + * message MyDuration { + * // duration must be less than 'P3D' [duration.lt] + * google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = { seconds: 259200 }]; + * } + * ``` + * + * @generated from field: google.protobuf.Timestamp lt = 3; + */ + value: Timestamp; + case: "lt"; + } | { + /** + * requires the timestamp field value to be less than or equal to the specified value (field <= value). If the field value doesn't meet the required conditions, an error message is generated. + * + * ```proto + * message MyTimestamp { + * // timestamp must be less than or equal to '2023-05-14T00:00:00Z' [timestamp.lte] + * google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.lte = { seconds: 1678867200 }]; + * } + * ``` + * + * @generated from field: google.protobuf.Timestamp lte = 4; + */ + value: Timestamp; + case: "lte"; + } | { + /** + * `lt_now` specifies that this field, of the `google.protobuf.Timestamp` type, must be less than the current time. `lt_now` can only be used with the `within` rule. + * + * ```proto + * message MyTimestamp { + * // value must be less than now + * google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.lt_now = true]; + * } + * ``` + * + * @generated from field: bool lt_now = 7; + */ + value: boolean; + case: "ltNow"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from oneof buf.validate.TimestampRules.greater_than + */ + greaterThan: { + /** + * `gt` requires the timestamp field value to be greater than the specified + * value (exclusive). If the value of `gt` is larger than a specified `lt` + * or `lte`, the range is reversed, and the field value must be outside the + * specified range. If the field value doesn't meet the required conditions, + * an error message is generated. + * + * ```proto + * message MyTimestamp { + * // timestamp must be greater than '2023-01-01T00:00:00Z' [timestamp.gt] + * google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.gt = { seconds: 1672444800 }]; + * + * // timestamp must be greater than '2023-01-01T00:00:00Z' and less than '2023-01-02T00:00:00Z' [timestamp.gt_lt] + * google.protobuf.Timestamp another_value = 2 [(buf.validate.field).timestamp = { gt: { seconds: 1672444800 }, lt: { seconds: 1672531200 } }]; + * + * // timestamp must be greater than '2023-01-02T00:00:00Z' or less than '2023-01-01T00:00:00Z' [timestamp.gt_lt_exclusive] + * google.protobuf.Timestamp other_value = 3 [(buf.validate.field).timestamp = { gt: { seconds: 1672531200 }, lt: { seconds: 1672444800 } }]; + * } + * ``` + * + * @generated from field: google.protobuf.Timestamp gt = 5; + */ + value: Timestamp; + case: "gt"; + } | { + /** + * `gte` requires the timestamp field value to be greater than or equal to the + * specified value (exclusive). If the value of `gte` is larger than a + * specified `lt` or `lte`, the range is reversed, and the field value + * must be outside the specified range. If the field value doesn't meet + * the required conditions, an error message is generated. + * + * ```proto + * message MyTimestamp { + * // timestamp must be greater than or equal to '2023-01-01T00:00:00Z' [timestamp.gte] + * google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.gte = { seconds: 1672444800 }]; + * + * // timestamp must be greater than or equal to '2023-01-01T00:00:00Z' and less than '2023-01-02T00:00:00Z' [timestamp.gte_lt] + * google.protobuf.Timestamp another_value = 2 [(buf.validate.field).timestamp = { gte: { seconds: 1672444800 }, lt: { seconds: 1672531200 } }]; + * + * // timestamp must be greater than or equal to '2023-01-02T00:00:00Z' or less than '2023-01-01T00:00:00Z' [timestamp.gte_lt_exclusive] + * google.protobuf.Timestamp other_value = 3 [(buf.validate.field).timestamp = { gte: { seconds: 1672531200 }, lt: { seconds: 1672444800 } }]; + * } + * ``` + * + * @generated from field: google.protobuf.Timestamp gte = 6; + */ + value: Timestamp; + case: "gte"; + } | { + /** + * `gt_now` specifies that this field, of the `google.protobuf.Timestamp` type, must be greater than the current time. `gt_now` can only be used with the `within` rule. + * + * ```proto + * message MyTimestamp { + * // value must be greater than now + * google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.gt_now = true]; + * } + * ``` + * + * @generated from field: bool gt_now = 8; + */ + value: boolean; + case: "gtNow"; + } | { case: undefined; value?: undefined }; + + /** + * `within` specifies that this field, of the `google.protobuf.Timestamp` type, must be within the specified duration of the current time. If the field value isn't within the duration, an error message is generated. + * + * ```proto + * message MyTimestamp { + * // value must be within 1 hour of now + * google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.within = {seconds: 3600}]; + * } + * ``` + * + * @generated from field: optional google.protobuf.Duration within = 9; + */ + within?: Duration; + + /** + * `example` specifies values that the field may have. These values SHOULD + * conform to other rules. `example` values will not impact validation + * but may be used as helpful guidance on how to populate the given field. + * + * ```proto + * message MyTimestamp { + * google.protobuf.Timestamp value = 1 [ + * (buf.validate.field).timestamp.example = { seconds: 1672444800 }, + * (buf.validate.field).timestamp.example = { seconds: 1672531200 }, + * ]; + * } + * ``` + * + * @generated from field: repeated google.protobuf.Timestamp example = 10; + */ + example: Timestamp[]; +}; + +/** + * Describes the message buf.validate.TimestampRules. + * Use `create(TimestampRulesSchema)` to create a new message. + */ +export const TimestampRulesSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 27); + +/** + * `Violations` is a collection of `Violation` messages. This message type is returned by + * Protovalidate when a proto message fails to meet the requirements set by the `Rule` validation rules. + * Each individual violation is represented by a `Violation` message. + * + * @generated from message buf.validate.Violations + */ +export type Violations = Message<"buf.validate.Violations"> & { + /** + * `violations` is a repeated field that contains all the `Violation` messages corresponding to the violations detected. + * + * @generated from field: repeated buf.validate.Violation violations = 1; + */ + violations: Violation[]; +}; + +/** + * Describes the message buf.validate.Violations. + * Use `create(ViolationsSchema)` to create a new message. + */ +export const ViolationsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 28); + +/** + * `Violation` represents a single instance where a validation rule, expressed + * as a `Rule`, was not met. It provides information about the field that + * caused the violation, the specific rule that wasn't fulfilled, and a + * human-readable error message. + * + * For example, consider the following message: + * + * ```proto + * message User { + * int32 age = 1 [(buf.validate.field).cel = { + * id: "user.age", + * expression: "this < 18 ? 'User must be at least 18 years old' : ''", + * }]; + * } + * ``` + * + * It could produce the following violation: + * + * ```json + * { + * "ruleId": "user.age", + * "message": "User must be at least 18 years old", + * "field": { + * "elements": [ + * { + * "fieldNumber": 1, + * "fieldName": "age", + * "fieldType": "TYPE_INT32" + * } + * ] + * }, + * "rule": { + * "elements": [ + * { + * "fieldNumber": 23, + * "fieldName": "cel", + * "fieldType": "TYPE_MESSAGE", + * "index": "0" + * } + * ] + * } + * } + * ``` + * + * @generated from message buf.validate.Violation + */ +export type Violation = Message<"buf.validate.Violation"> & { + /** + * `field` is a machine-readable path to the field that failed validation. + * This could be a nested field, in which case the path will include all the parent fields leading to the actual field that caused the violation. + * + * For example, consider the following message: + * + * ```proto + * message Message { + * bool a = 1 [(buf.validate.field).required = true]; + * } + * ``` + * + * It could produce the following violation: + * + * ```textproto + * violation { + * field { element { field_number: 1, field_name: "a", field_type: 8 } } + * ... + * } + * ``` + * + * @generated from field: optional buf.validate.FieldPath field = 5; + */ + field?: FieldPath; + + /** + * `rule` is a machine-readable path that points to the specific rule that failed validation. + * This will be a nested field starting from the FieldRules of the field that failed validation. + * For custom rules, this will provide the path of the rule, e.g. `cel[0]`. + * + * For example, consider the following message: + * + * ```proto + * message Message { + * bool a = 1 [(buf.validate.field).required = true]; + * bool b = 2 [(buf.validate.field).cel = { + * id: "custom_rule", + * expression: "!this ? 'b must be true': ''" + * }] + * } + * ``` + * + * It could produce the following violations: + * + * ```textproto + * violation { + * rule { element { field_number: 25, field_name: "required", field_type: 8 } } + * ... + * } + * violation { + * rule { element { field_number: 23, field_name: "cel", field_type: 11, index: 0 } } + * ... + * } + * ``` + * + * @generated from field: optional buf.validate.FieldPath rule = 6; + */ + rule?: FieldPath; + + /** + * `rule_id` is the unique identifier of the `Rule` that was not fulfilled. + * This is the same `id` that was specified in the `Rule` message, allowing easy tracing of which rule was violated. + * + * @generated from field: optional string rule_id = 2; + */ + ruleId: string; + + /** + * `message` is a human-readable error message that describes the nature of the violation. + * This can be the default error message from the violated `Rule`, or it can be a custom message that gives more context about the violation. + * + * @generated from field: optional string message = 3; + */ + message: string; + + /** + * `for_key` indicates whether the violation was caused by a map key, rather than a value. + * + * @generated from field: optional bool for_key = 4; + */ + forKey: boolean; +}; + +/** + * Describes the message buf.validate.Violation. + * Use `create(ViolationSchema)` to create a new message. + */ +export const ViolationSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 29); + +/** + * `FieldPath` provides a path to a nested protobuf field. + * + * This message provides enough information to render a dotted field path even without protobuf descriptors. + * It also provides enough information to resolve a nested field through unknown wire data. + * + * @generated from message buf.validate.FieldPath + */ +export type FieldPath = Message<"buf.validate.FieldPath"> & { + /** + * `elements` contains each element of the path, starting from the root and recursing downward. + * + * @generated from field: repeated buf.validate.FieldPathElement elements = 1; + */ + elements: FieldPathElement[]; +}; + +/** + * Describes the message buf.validate.FieldPath. + * Use `create(FieldPathSchema)` to create a new message. + */ +export const FieldPathSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 30); + +/** + * `FieldPathElement` provides enough information to nest through a single protobuf field. + * + * If the selected field is a map or repeated field, the `subscript` value selects a specific element from it. + * A path that refers to a value nested under a map key or repeated field index will have a `subscript` value. + * The `field_type` field allows unambiguous resolution of a field even if descriptors are not available. + * + * @generated from message buf.validate.FieldPathElement + */ +export type FieldPathElement = Message<"buf.validate.FieldPathElement"> & { + /** + * `field_number` is the field number this path element refers to. + * + * @generated from field: optional int32 field_number = 1; + */ + fieldNumber: number; + + /** + * `field_name` contains the field name this path element refers to. + * This can be used to display a human-readable path even if the field number is unknown. + * + * @generated from field: optional string field_name = 2; + */ + fieldName: string; + + /** + * `field_type` specifies the type of this field. When using reflection, this value is not needed. + * + * This value is provided to make it possible to traverse unknown fields through wire data. + * When traversing wire data, be mindful of both packed[1] and delimited[2] encoding schemes. + * + * [1]: https://protobuf.dev/programming-guides/encoding/#packed + * [2]: https://protobuf.dev/programming-guides/encoding/#groups + * + * N.B.: Although groups are deprecated, the corresponding delimited encoding scheme is not, and + * can be explicitly used in Protocol Buffers 2023 Edition. + * + * @generated from field: optional google.protobuf.FieldDescriptorProto.Type field_type = 3; + */ + fieldType: FieldDescriptorProto_Type; + + /** + * `key_type` specifies the map key type of this field. This value is useful when traversing + * unknown fields through wire data: specifically, it allows handling the differences between + * different integer encodings. + * + * @generated from field: optional google.protobuf.FieldDescriptorProto.Type key_type = 4; + */ + keyType: FieldDescriptorProto_Type; + + /** + * `value_type` specifies map value type of this field. This is useful if you want to display a + * value inside unknown fields through wire data. + * + * @generated from field: optional google.protobuf.FieldDescriptorProto.Type value_type = 5; + */ + valueType: FieldDescriptorProto_Type; + + /** + * `subscript` contains a repeated index or map key, if this path element nests into a repeated or map field. + * + * @generated from oneof buf.validate.FieldPathElement.subscript + */ + subscript: { + /** + * `index` specifies a 0-based index into a repeated field. + * + * @generated from field: uint64 index = 6; + */ + value: bigint; + case: "index"; + } | { + /** + * `bool_key` specifies a map key of type bool. + * + * @generated from field: bool bool_key = 7; + */ + value: boolean; + case: "boolKey"; + } | { + /** + * `int_key` specifies a map key of type int32, int64, sint32, sint64, sfixed32 or sfixed64. + * + * @generated from field: int64 int_key = 8; + */ + value: bigint; + case: "intKey"; + } | { + /** + * `uint_key` specifies a map key of type uint32, uint64, fixed32 or fixed64. + * + * @generated from field: uint64 uint_key = 9; + */ + value: bigint; + case: "uintKey"; + } | { + /** + * `string_key` specifies a map key of type string. + * + * @generated from field: string string_key = 10; + */ + value: string; + case: "stringKey"; + } | { case: undefined; value?: undefined }; +}; + +/** + * Describes the message buf.validate.FieldPathElement. + * Use `create(FieldPathElementSchema)` to create a new message. + */ +export const FieldPathElementSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_buf_validate_validate, 31); + +/** + * Specifies how `FieldRules.ignore` behaves, depending on the field's value, and + * whether the field tracks presence. + * + * @generated from enum buf.validate.Ignore + */ +export enum Ignore { + /** + * Ignore rules if the field tracks presence and is unset. This is the default + * behavior. + * + * In proto3, only message fields, members of a Protobuf `oneof`, and fields + * with the `optional` label track presence. Consequently, the following fields + * are always validated, whether a value is set or not: + * + * ```proto + * syntax="proto3"; + * + * message RulesApply { + * string email = 1 [ + * (buf.validate.field).string.email = true + * ]; + * int32 age = 2 [ + * (buf.validate.field).int32.gt = 0 + * ]; + * repeated string labels = 3 [ + * (buf.validate.field).repeated.min_items = 1 + * ]; + * } + * ``` + * + * In contrast, the following fields track presence, and are only validated if + * a value is set: + * + * ```proto + * syntax="proto3"; + * + * message RulesApplyIfSet { + * optional string email = 1 [ + * (buf.validate.field).string.email = true + * ]; + * oneof ref { + * string reference = 2 [ + * (buf.validate.field).string.uuid = true + * ]; + * string name = 3 [ + * (buf.validate.field).string.min_len = 4 + * ]; + * } + * SomeMessage msg = 4 [ + * (buf.validate.field).cel = {/* ... *\/} + * ]; + * } + * ``` + * + * To ensure that such a field is set, add the `required` rule. + * + * To learn which fields track presence, see the + * [Field Presence cheat sheet](https://protobuf.dev/programming-guides/field_presence/#cheat). + * + * @generated from enum value: IGNORE_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + + /** + * Ignore rules if the field is unset, or set to the zero value. + * + * The zero value depends on the field type: + * - For strings, the zero value is the empty string. + * - For bytes, the zero value is empty bytes. + * - For bool, the zero value is false. + * - For numeric types, the zero value is zero. + * - For enums, the zero value is the first defined enum value. + * - For repeated fields, the zero is an empty list. + * - For map fields, the zero is an empty map. + * - For message fields, absence of the message (typically a null-value) is considered zero value. + * + * For fields that track presence (e.g. adding the `optional` label in proto3), + * this a no-op and behavior is the same as the default `IGNORE_UNSPECIFIED`. + * + * @generated from enum value: IGNORE_IF_ZERO_VALUE = 1; + */ + IF_ZERO_VALUE = 1, + + /** + * Always ignore rules, including the `required` rule. + * + * This is useful for ignoring the rules of a referenced message, or to + * temporarily ignore rules during development. + * + * ```proto + * message MyMessage { + * // The field's rules will always be ignored, including any validations + * // on value's fields. + * MyOtherMessage value = 1 [ + * (buf.validate.field).ignore = IGNORE_ALWAYS + * ]; + * } + * ``` + * + * @generated from enum value: IGNORE_ALWAYS = 3; + */ + ALWAYS = 3, +} + +/** + * Describes the enum buf.validate.Ignore. + */ +export const IgnoreSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_buf_validate_validate, 0); + +/** + * KnownRegex contains some well-known patterns. + * + * @generated from enum buf.validate.KnownRegex + */ +export enum KnownRegex { + /** + * @generated from enum value: KNOWN_REGEX_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + + /** + * HTTP header name as defined by [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2). + * + * @generated from enum value: KNOWN_REGEX_HTTP_HEADER_NAME = 1; + */ + HTTP_HEADER_NAME = 1, + + /** + * HTTP header value as defined by [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4). + * + * @generated from enum value: KNOWN_REGEX_HTTP_HEADER_VALUE = 2; + */ + HTTP_HEADER_VALUE = 2, +} + +/** + * Describes the enum buf.validate.KnownRegex. + */ +export const KnownRegexSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_buf_validate_validate, 1); + +/** + * Rules specify the validations to be performed on this message. By default, + * no validation is performed against a message. + * + * @generated from extension: optional buf.validate.MessageRules message = 1159; + */ +export const message: GenExtension = /*@__PURE__*/ + extDesc(file_buf_validate_validate, 0); + +/** + * Rules specify the validations to be performed on this oneof. By default, + * no validation is performed against a oneof. + * + * @generated from extension: optional buf.validate.OneofRules oneof = 1159; + */ +export const oneof: GenExtension = /*@__PURE__*/ + extDesc(file_buf_validate_validate, 1); + +/** + * Rules specify the validations to be performed on this field. By default, + * no validation is performed against a field. + * + * @generated from extension: optional buf.validate.FieldRules field = 1159; + */ +export const field: GenExtension = /*@__PURE__*/ + extDesc(file_buf_validate_validate, 2); + +/** + * Specifies predefined rules. When extending a standard rule message, + * this adds additional CEL expressions that apply when the extension is used. + * + * ```proto + * extend buf.validate.Int32Rules { + * bool is_zero [(buf.validate.predefined).cel = { + * id: "int32.is_zero", + * message: "value must be zero", + * expression: "!rule || this == 0", + * }]; + * } + * + * message Foo { + * int32 reserved = 1 [(buf.validate.field).int32.(is_zero) = true]; + * } + * ``` + * + * @generated from extension: optional buf.validate.PredefinedRules predefined = 1160; + */ +export const predefined: GenExtension = /*@__PURE__*/ + extDesc(file_buf_validate_validate, 3); + diff --git a/web-dashboard/src/gen/greet/v1/greet_pb.ts b/web-dashboard/src/gen/greet/v1/greet_pb.ts new file mode 100644 index 0000000..8ba0002 --- /dev/null +++ b/web-dashboard/src/gen/greet/v1/greet_pb.ts @@ -0,0 +1,64 @@ +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated from file greet/v1/greet.proto (package greet.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import { file_buf_validate_validate } from "../../buf/validate/validate_pb"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file greet/v1/greet.proto. + */ +export const file_greet_v1_greet: GenFile = /*@__PURE__*/ + fileDesc("ChRncmVldC92MS9ncmVldC5wcm90bxIIZ3JlZXQudjEiJwoMR3JlZXRSZXF1ZXN0EhcKBG5hbWUYASABKAlCCbpIBnIEEAEYMiIhCg1HcmVldFJlc3BvbnNlEhAKCGdyZWV0aW5nGAEgASgJMkoKDEdyZWV0U2VydmljZRI6CgVHcmVldBIWLmdyZWV0LnYxLkdyZWV0UmVxdWVzdBoXLmdyZWV0LnYxLkdyZWV0UmVzcG9uc2UiAEKTAQoMY29tLmdyZWV0LnYxQgpHcmVldFByb3RvUAFaNmdpdGh1Yi5jb20vTkxMQ29tbXVuaXR5L2hlaW1kYWxsci9nZW4vZ3JlZXQvdjE7Z3JlZXR2MaICA0dYWKoCCEdyZWV0LlYxygIIR3JlZXRcVjHiAhRHcmVldFxWMVxHUEJNZXRhZGF0YeoCCUdyZWV0OjpWMWIGcHJvdG8z", [file_buf_validate_validate]); + +/** + * @generated from message greet.v1.GreetRequest + */ +export type GreetRequest = Message<"greet.v1.GreetRequest"> & { + /** + * @generated from field: string name = 1; + */ + name: string; +}; + +/** + * Describes the message greet.v1.GreetRequest. + * Use `create(GreetRequestSchema)` to create a new message. + */ +export const GreetRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_greet_v1_greet, 0); + +/** + * @generated from message greet.v1.GreetResponse + */ +export type GreetResponse = Message<"greet.v1.GreetResponse"> & { + /** + * @generated from field: string greeting = 1; + */ + greeting: string; +}; + +/** + * Describes the message greet.v1.GreetResponse. + * Use `create(GreetResponseSchema)` to create a new message. + */ +export const GreetResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_greet_v1_greet, 1); + +/** + * @generated from service greet.v1.GreetService + */ +export const GreetService: GenService<{ + /** + * @generated from rpc greet.v1.GreetService.Greet + */ + greet: { + methodKind: "unary"; + input: typeof GreetRequestSchema; + output: typeof GreetResponseSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_greet_v1_greet, 0); + diff --git a/web-dashboard/src/gen/heimdallr/v1/auth_pb.ts b/web-dashboard/src/gen/heimdallr/v1/auth_pb.ts new file mode 100644 index 0000000..e429d32 --- /dev/null +++ b/web-dashboard/src/gen/heimdallr/v1/auth_pb.ts @@ -0,0 +1,265 @@ +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated from file heimdallr/v1/auth.proto (package heimdallr.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file heimdallr/v1/auth.proto. + */ +export const file_heimdallr_v1_auth: GenFile = /*@__PURE__*/ + fileDesc("ChdoZWltZGFsbHIvdjEvYXV0aC5wcm90bxIMaGVpbWRhbGxyLnYxIjQKBFVzZXISCgoCaWQYASABKAkSEAoIdXNlcm5hbWUYAiABKAkSDgoGYXZhdGFyGAMgASgJIi8KBUd1aWxkEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEaWNvbhgDIAEoCSIUChJHZXRMb2dpblVSTFJlcXVlc3QiIgoTR2V0TG9naW5VUkxSZXNwb25zZRILCgN1cmwYASABKAkiIwoTRXhjaGFuZ2VDb2RlUmVxdWVzdBIMCgRjb2RlGAEgASgJIjgKFEV4Y2hhbmdlQ29kZVJlc3BvbnNlEiAKBHVzZXIYAiABKAsyEi5oZWltZGFsbHIudjEuVXNlciIXChVHZXRDdXJyZW50VXNlclJlcXVlc3QiOgoWR2V0Q3VycmVudFVzZXJSZXNwb25zZRIgCgR1c2VyGAEgASgLMhIuaGVpbWRhbGxyLnYxLlVzZXIiEwoRTGlzdEd1aWxkc1JlcXVlc3QiOQoSTGlzdEd1aWxkc1Jlc3BvbnNlEiMKBmd1aWxkcxgBIAMoCzITLmhlaW1kYWxsci52MS5HdWlsZCIPCg1Mb2dvdXRSZXF1ZXN0IhAKDkxvZ291dFJlc3BvbnNlMqsDCgtBdXRoU2VydmljZRJSCgtHZXRMb2dpblVSTBIgLmhlaW1kYWxsci52MS5HZXRMb2dpblVSTFJlcXVlc3QaIS5oZWltZGFsbHIudjEuR2V0TG9naW5VUkxSZXNwb25zZRJVCgxFeGNoYW5nZUNvZGUSIS5oZWltZGFsbHIudjEuRXhjaGFuZ2VDb2RlUmVxdWVzdBoiLmhlaW1kYWxsci52MS5FeGNoYW5nZUNvZGVSZXNwb25zZRJbCg5HZXRDdXJyZW50VXNlchIjLmhlaW1kYWxsci52MS5HZXRDdXJyZW50VXNlclJlcXVlc3QaJC5oZWltZGFsbHIudjEuR2V0Q3VycmVudFVzZXJSZXNwb25zZRJPCgpMaXN0R3VpbGRzEh8uaGVpbWRhbGxyLnYxLkxpc3RHdWlsZHNSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLkxpc3RHdWlsZHNSZXNwb25zZRJDCgZMb2dvdXQSGy5oZWltZGFsbHIudjEuTG9nb3V0UmVxdWVzdBocLmhlaW1kYWxsci52MS5Mb2dvdXRSZXNwb25zZUKuAQoQY29tLmhlaW1kYWxsci52MUIJQXV0aFByb3RvUAFaPmdpdGh1Yi5jb20vTkxMQ29tbXVuaXR5L2hlaW1kYWxsci9nZW4vaGVpbWRhbGxyL3YxO2hlaW1kYWxscnYxogIDSFhYqgIMSGVpbWRhbGxyLlYxygIMSGVpbWRhbGxyXFYx4gIYSGVpbWRhbGxyXFYxXEdQQk1ldGFkYXRh6gINSGVpbWRhbGxyOjpWMWIGcHJvdG8z"); + +/** + * @generated from message heimdallr.v1.User + */ +export type User = Message<"heimdallr.v1.User"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string username = 2; + */ + username: string; + + /** + * @generated from field: string avatar = 3; + */ + avatar: string; +}; + +/** + * Describes the message heimdallr.v1.User. + * Use `create(UserSchema)` to create a new message. + */ +export const UserSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 0); + +/** + * @generated from message heimdallr.v1.Guild + */ +export type Guild = Message<"heimdallr.v1.Guild"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string name = 2; + */ + name: string; + + /** + * @generated from field: string icon = 3; + */ + icon: string; +}; + +/** + * Describes the message heimdallr.v1.Guild. + * Use `create(GuildSchema)` to create a new message. + */ +export const GuildSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 1); + +/** + * @generated from message heimdallr.v1.GetLoginURLRequest + */ +export type GetLoginURLRequest = Message<"heimdallr.v1.GetLoginURLRequest"> & { +}; + +/** + * Describes the message heimdallr.v1.GetLoginURLRequest. + * Use `create(GetLoginURLRequestSchema)` to create a new message. + */ +export const GetLoginURLRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 2); + +/** + * @generated from message heimdallr.v1.GetLoginURLResponse + */ +export type GetLoginURLResponse = Message<"heimdallr.v1.GetLoginURLResponse"> & { + /** + * @generated from field: string url = 1; + */ + url: string; +}; + +/** + * Describes the message heimdallr.v1.GetLoginURLResponse. + * Use `create(GetLoginURLResponseSchema)` to create a new message. + */ +export const GetLoginURLResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 3); + +/** + * @generated from message heimdallr.v1.ExchangeCodeRequest + */ +export type ExchangeCodeRequest = Message<"heimdallr.v1.ExchangeCodeRequest"> & { + /** + * @generated from field: string code = 1; + */ + code: string; +}; + +/** + * Describes the message heimdallr.v1.ExchangeCodeRequest. + * Use `create(ExchangeCodeRequestSchema)` to create a new message. + */ +export const ExchangeCodeRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 4); + +/** + * @generated from message heimdallr.v1.ExchangeCodeResponse + */ +export type ExchangeCodeResponse = Message<"heimdallr.v1.ExchangeCodeResponse"> & { + /** + * @generated from field: heimdallr.v1.User user = 2; + */ + user?: User; +}; + +/** + * Describes the message heimdallr.v1.ExchangeCodeResponse. + * Use `create(ExchangeCodeResponseSchema)` to create a new message. + */ +export const ExchangeCodeResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 5); + +/** + * @generated from message heimdallr.v1.GetCurrentUserRequest + */ +export type GetCurrentUserRequest = Message<"heimdallr.v1.GetCurrentUserRequest"> & { +}; + +/** + * Describes the message heimdallr.v1.GetCurrentUserRequest. + * Use `create(GetCurrentUserRequestSchema)` to create a new message. + */ +export const GetCurrentUserRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 6); + +/** + * @generated from message heimdallr.v1.GetCurrentUserResponse + */ +export type GetCurrentUserResponse = Message<"heimdallr.v1.GetCurrentUserResponse"> & { + /** + * @generated from field: heimdallr.v1.User user = 1; + */ + user?: User; +}; + +/** + * Describes the message heimdallr.v1.GetCurrentUserResponse. + * Use `create(GetCurrentUserResponseSchema)` to create a new message. + */ +export const GetCurrentUserResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 7); + +/** + * @generated from message heimdallr.v1.ListGuildsRequest + */ +export type ListGuildsRequest = Message<"heimdallr.v1.ListGuildsRequest"> & { +}; + +/** + * Describes the message heimdallr.v1.ListGuildsRequest. + * Use `create(ListGuildsRequestSchema)` to create a new message. + */ +export const ListGuildsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 8); + +/** + * @generated from message heimdallr.v1.ListGuildsResponse + */ +export type ListGuildsResponse = Message<"heimdallr.v1.ListGuildsResponse"> & { + /** + * @generated from field: repeated heimdallr.v1.Guild guilds = 1; + */ + guilds: Guild[]; +}; + +/** + * Describes the message heimdallr.v1.ListGuildsResponse. + * Use `create(ListGuildsResponseSchema)` to create a new message. + */ +export const ListGuildsResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 9); + +/** + * @generated from message heimdallr.v1.LogoutRequest + */ +export type LogoutRequest = Message<"heimdallr.v1.LogoutRequest"> & { +}; + +/** + * Describes the message heimdallr.v1.LogoutRequest. + * Use `create(LogoutRequestSchema)` to create a new message. + */ +export const LogoutRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 10); + +/** + * @generated from message heimdallr.v1.LogoutResponse + */ +export type LogoutResponse = Message<"heimdallr.v1.LogoutResponse"> & { +}; + +/** + * Describes the message heimdallr.v1.LogoutResponse. + * Use `create(LogoutResponseSchema)` to create a new message. + */ +export const LogoutResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_auth, 11); + +/** + * @generated from service heimdallr.v1.AuthService + */ +export const AuthService: GenService<{ + /** + * @generated from rpc heimdallr.v1.AuthService.GetLoginURL + */ + getLoginURL: { + methodKind: "unary"; + input: typeof GetLoginURLRequestSchema; + output: typeof GetLoginURLResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.AuthService.ExchangeCode + */ + exchangeCode: { + methodKind: "unary"; + input: typeof ExchangeCodeRequestSchema; + output: typeof ExchangeCodeResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.AuthService.GetCurrentUser + */ + getCurrentUser: { + methodKind: "unary"; + input: typeof GetCurrentUserRequestSchema; + output: typeof GetCurrentUserResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.AuthService.ListGuilds + */ + listGuilds: { + methodKind: "unary"; + input: typeof ListGuildsRequestSchema; + output: typeof ListGuildsResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.AuthService.Logout + */ + logout: { + methodKind: "unary"; + input: typeof LogoutRequestSchema; + output: typeof LogoutResponseSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_heimdallr_v1_auth, 0); + diff --git a/web-dashboard/src/gen/heimdallr/v1/guild_settings_pb.ts b/web-dashboard/src/gen/heimdallr/v1/guild_settings_pb.ts new file mode 100644 index 0000000..8cc1151 --- /dev/null +++ b/web-dashboard/src/gen/heimdallr/v1/guild_settings_pb.ts @@ -0,0 +1,922 @@ +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated from file heimdallr/v1/guild_settings.proto (package heimdallr.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file heimdallr/v1/guild_settings.proto. + */ +export const file_heimdallr_v1_guild_settings: GenFile = /*@__PURE__*/ + fileDesc("CiFoZWltZGFsbHIvdjEvZ3VpbGRfc2V0dGluZ3MucHJvdG8SDGhlaW1kYWxsci52MSIoChRHZXRNb2RDaGFubmVsUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJNChdVcGRhdGVNb2RDaGFubmVsUmVxdWVzdBIyCghzZXR0aW5ncxgBIAEoCzIgLmhlaW1kYWxsci52MS5Nb2RDaGFubmVsU2V0dGluZ3MiQQoSTW9kQ2hhbm5lbFNldHRpbmdzEhAKCGd1aWxkX2lkGAEgASgJEhkKEW1vZGVyYXRvcl9jaGFubmVsGAIgASgJIjAKHEdldEluZnJhY3Rpb25TZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiVQofVXBkYXRlSW5mcmFjdGlvblNldHRpbmdzUmVxdWVzdBIyCghzZXR0aW5ncxgBIAEoCzIgLmhlaW1kYWxsci52MS5JbmZyYWN0aW9uU2V0dGluZ3MiigEKEkluZnJhY3Rpb25TZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIWCg5oYWxmX2xpZmVfZGF5cxgCIAEoARIiChpub3RpZnlfb25fd2FybmVkX3VzZXJfam9pbhgDIAEoCBImCh5ub3RpZnlfd2Fybl9zZXZlcml0eV90aHJlc2hvbGQYBCABKAEiLgoaR2V0R2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiUQodVXBkYXRlR2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QSMAoIc2V0dGluZ3MYASABKAsyHi5oZWltZGFsbHIudjEuR2F0ZWtlZXBTZXR0aW5ncyLdAQoQR2F0ZWtlZXBTZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIPCgdlbmFibGVkGAIgASgIEhQKDHBlbmRpbmdfcm9sZRgDIAEoCRIVCg1hcHByb3ZlZF9yb2xlGAQgASgJEiAKGGFkZF9wZW5kaW5nX3JvbGVfb25fam9pbhgFIAEoCBIYChBhcHByb3ZlZF9tZXNzYWdlGAYgASgJEhsKE2FwcHJvdmVkX21lc3NhZ2VfdjIYByABKAgSIAoYYXBwcm92ZWRfbWVzc2FnZV92Ml9qc29uGAggASgJIi8KG0dldEpvaW5MZWF2ZVNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJTCh5VcGRhdGVKb2luTGVhdmVTZXR0aW5nc1JlcXVlc3QSMQoIc2V0dGluZ3MYASABKAsyHy5oZWltZGFsbHIudjEuSm9pbkxlYXZlU2V0dGluZ3MikAIKEUpvaW5MZWF2ZVNldHRpbmdzEhAKCGd1aWxkX2lkGAEgASgJEhwKFGpvaW5fbWVzc2FnZV9lbmFibGVkGAIgASgIEhQKDGpvaW5fbWVzc2FnZRgDIAEoCRIdChVsZWF2ZV9tZXNzYWdlX2VuYWJsZWQYBCABKAgSFQoNbGVhdmVfbWVzc2FnZRgFIAEoCRIPCgdjaGFubmVsGAYgASgJEhcKD2pvaW5fbWVzc2FnZV92MhgHIAEoCBIcChRqb2luX21lc3NhZ2VfdjJfanNvbhgIIAEoCRIYChBsZWF2ZV9tZXNzYWdlX3YyGAkgASgIEh0KFWxlYXZlX21lc3NhZ2VfdjJfanNvbhgKIAEoCSIuChpHZXRBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJRCh1VcGRhdGVBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBIwCghzZXR0aW5ncxgBIAEoCzIeLmhlaW1kYWxsci52MS5BbnRpU3BhbVNldHRpbmdzIl4KEEFudGlTcGFtU2V0dGluZ3MSEAoIZ3VpbGRfaWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCBINCgVjb3VudBgDIAEoBRIYChBjb29sZG93bl9zZWNvbmRzGAQgASgFIi8KG0dldEJhbkZvb3RlclNldHRpbmdzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSJTCh5VcGRhdGVCYW5Gb290ZXJTZXR0aW5nc1JlcXVlc3QSMQoIc2V0dGluZ3MYASABKAsyHy5oZWltZGFsbHIudjEuQmFuRm9vdGVyU2V0dGluZ3MiSgoRQmFuRm9vdGVyU2V0dGluZ3MSEAoIZ3VpbGRfaWQYASABKAkSDgoGZm9vdGVyGAIgASgJEhMKC2Fsd2F5c19zZW5kGAMgASgIIi0KGUdldE1vZG1haWxTZXR0aW5nc1JlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkiTwocVXBkYXRlTW9kbWFpbFNldHRpbmdzUmVxdWVzdBIvCghzZXR0aW5ncxgBIAEoCzIdLmhlaW1kYWxsci52MS5Nb2RtYWlsU2V0dGluZ3MiggEKD01vZG1haWxTZXR0aW5ncxIQCghndWlsZF9pZBgBIAEoCRIeChZyZXBvcnRfdGhyZWFkc19jaGFubmVsGAIgASgJEiMKG3JlcG9ydF9ub3RpZmljYXRpb25fY2hhbm5lbBgDIAEoCRIYChByZXBvcnRfcGluZ19yb2xlGAQgASgJIlYKB0NoYW5uZWwSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIMCgR0eXBlGAMgASgFEhAKCHBvc2l0aW9uGAQgASgFEhEKCXBhcmVudF9pZBgFIAEoCSJSCgRSb2xlEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDQoFY29sb3IYAyABKAUSEAoIcG9zaXRpb24YBCABKAUSDwoHbWFuYWdlZBgFIAEoCCInChNMaXN0Q2hhbm5lbHNSZXF1ZXN0EhAKCGd1aWxkX2lkGAEgASgJIj8KFExpc3RDaGFubmVsc1Jlc3BvbnNlEicKCGNoYW5uZWxzGAEgAygLMhUuaGVpbWRhbGxyLnYxLkNoYW5uZWwiJAoQTGlzdFJvbGVzUmVxdWVzdBIQCghndWlsZF9pZBgBIAEoCSI2ChFMaXN0Um9sZXNSZXNwb25zZRIhCgVyb2xlcxgBIAMoCzISLmhlaW1kYWxsci52MS5Sb2xlIl0KHFNlbmRDb21wb25lbnRzTWVzc2FnZVJlcXVlc3QSEAoIZ3VpbGRfaWQYASABKAkSEgoKY2hhbm5lbF9pZBgCIAEoCRIXCg9jb21wb25lbnRzX2pzb24YAyABKAkiMwodU2VuZENvbXBvbmVudHNNZXNzYWdlUmVzcG9uc2USEgoKbWVzc2FnZV9pZBgBIAEoCSI/ChNUZW1wbGF0ZVBsYWNlaG9sZGVyEhMKC3BsYWNlaG9sZGVyGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJIiAKHkdldFRlbXBsYXRlUGxhY2Vob2xkZXJzUmVxdWVzdCJaCh9HZXRUZW1wbGF0ZVBsYWNlaG9sZGVyc1Jlc3BvbnNlEjcKDHBsYWNlaG9sZGVycxgBIAMoCzIhLmhlaW1kYWxsci52MS5UZW1wbGF0ZVBsYWNlaG9sZGVyMpsOChRHdWlsZFNldHRpbmdzU2VydmljZRJVCg1HZXRNb2RDaGFubmVsEiIuaGVpbWRhbGxyLnYxLkdldE1vZENoYW5uZWxSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLk1vZENoYW5uZWxTZXR0aW5ncxJbChBVcGRhdGVNb2RDaGFubmVsEiUuaGVpbWRhbGxyLnYxLlVwZGF0ZU1vZENoYW5uZWxSZXF1ZXN0GiAuaGVpbWRhbGxyLnYxLk1vZENoYW5uZWxTZXR0aW5ncxJlChVHZXRJbmZyYWN0aW9uU2V0dGluZ3MSKi5oZWltZGFsbHIudjEuR2V0SW5mcmFjdGlvblNldHRpbmdzUmVxdWVzdBogLmhlaW1kYWxsci52MS5JbmZyYWN0aW9uU2V0dGluZ3MSawoYVXBkYXRlSW5mcmFjdGlvblNldHRpbmdzEi0uaGVpbWRhbGxyLnYxLlVwZGF0ZUluZnJhY3Rpb25TZXR0aW5nc1JlcXVlc3QaIC5oZWltZGFsbHIudjEuSW5mcmFjdGlvblNldHRpbmdzEl8KE0dldEdhdGVrZWVwU2V0dGluZ3MSKC5oZWltZGFsbHIudjEuR2V0R2F0ZWtlZXBTZXR0aW5nc1JlcXVlc3QaHi5oZWltZGFsbHIudjEuR2F0ZWtlZXBTZXR0aW5ncxJlChZVcGRhdGVHYXRla2VlcFNldHRpbmdzEisuaGVpbWRhbGxyLnYxLlVwZGF0ZUdhdGVrZWVwU2V0dGluZ3NSZXF1ZXN0Gh4uaGVpbWRhbGxyLnYxLkdhdGVrZWVwU2V0dGluZ3MSYgoUR2V0Sm9pbkxlYXZlU2V0dGluZ3MSKS5oZWltZGFsbHIudjEuR2V0Sm9pbkxlYXZlU2V0dGluZ3NSZXF1ZXN0Gh8uaGVpbWRhbGxyLnYxLkpvaW5MZWF2ZVNldHRpbmdzEmgKF1VwZGF0ZUpvaW5MZWF2ZVNldHRpbmdzEiwuaGVpbWRhbGxyLnYxLlVwZGF0ZUpvaW5MZWF2ZVNldHRpbmdzUmVxdWVzdBofLmhlaW1kYWxsci52MS5Kb2luTGVhdmVTZXR0aW5ncxJfChNHZXRBbnRpU3BhbVNldHRpbmdzEiguaGVpbWRhbGxyLnYxLkdldEFudGlTcGFtU2V0dGluZ3NSZXF1ZXN0Gh4uaGVpbWRhbGxyLnYxLkFudGlTcGFtU2V0dGluZ3MSZQoWVXBkYXRlQW50aVNwYW1TZXR0aW5ncxIrLmhlaW1kYWxsci52MS5VcGRhdGVBbnRpU3BhbVNldHRpbmdzUmVxdWVzdBoeLmhlaW1kYWxsci52MS5BbnRpU3BhbVNldHRpbmdzEmIKFEdldEJhbkZvb3RlclNldHRpbmdzEikuaGVpbWRhbGxyLnYxLkdldEJhbkZvb3RlclNldHRpbmdzUmVxdWVzdBofLmhlaW1kYWxsci52MS5CYW5Gb290ZXJTZXR0aW5ncxJoChdVcGRhdGVCYW5Gb290ZXJTZXR0aW5ncxIsLmhlaW1kYWxsci52MS5VcGRhdGVCYW5Gb290ZXJTZXR0aW5nc1JlcXVlc3QaHy5oZWltZGFsbHIudjEuQmFuRm9vdGVyU2V0dGluZ3MSXAoSR2V0TW9kbWFpbFNldHRpbmdzEicuaGVpbWRhbGxyLnYxLkdldE1vZG1haWxTZXR0aW5nc1JlcXVlc3QaHS5oZWltZGFsbHIudjEuTW9kbWFpbFNldHRpbmdzEmIKFVVwZGF0ZU1vZG1haWxTZXR0aW5ncxIqLmhlaW1kYWxsci52MS5VcGRhdGVNb2RtYWlsU2V0dGluZ3NSZXF1ZXN0Gh0uaGVpbWRhbGxyLnYxLk1vZG1haWxTZXR0aW5ncxJVCgxMaXN0Q2hhbm5lbHMSIS5oZWltZGFsbHIudjEuTGlzdENoYW5uZWxzUmVxdWVzdBoiLmhlaW1kYWxsci52MS5MaXN0Q2hhbm5lbHNSZXNwb25zZRJMCglMaXN0Um9sZXMSHi5oZWltZGFsbHIudjEuTGlzdFJvbGVzUmVxdWVzdBofLmhlaW1kYWxsci52MS5MaXN0Um9sZXNSZXNwb25zZRJ2ChdHZXRUZW1wbGF0ZVBsYWNlaG9sZGVycxIsLmhlaW1kYWxsci52MS5HZXRUZW1wbGF0ZVBsYWNlaG9sZGVyc1JlcXVlc3QaLS5oZWltZGFsbHIudjEuR2V0VGVtcGxhdGVQbGFjZWhvbGRlcnNSZXNwb25zZRJwChVTZW5kQ29tcG9uZW50c01lc3NhZ2USKi5oZWltZGFsbHIudjEuU2VuZENvbXBvbmVudHNNZXNzYWdlUmVxdWVzdBorLmhlaW1kYWxsci52MS5TZW5kQ29tcG9uZW50c01lc3NhZ2VSZXNwb25zZUK3AQoQY29tLmhlaW1kYWxsci52MUISR3VpbGRTZXR0aW5nc1Byb3RvUAFaPmdpdGh1Yi5jb20vTkxMQ29tbXVuaXR5L2hlaW1kYWxsci9nZW4vaGVpbWRhbGxyL3YxO2hlaW1kYWxscnYxogIDSFhYqgIMSGVpbWRhbGxyLlYxygIMSGVpbWRhbGxyXFYx4gIYSGVpbWRhbGxyXFYxXEdQQk1ldGFkYXRh6gINSGVpbWRhbGxyOjpWMWIGcHJvdG8z"); + +/** + * ModChannel + * + * @generated from message heimdallr.v1.GetModChannelRequest + */ +export type GetModChannelRequest = Message<"heimdallr.v1.GetModChannelRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetModChannelRequest. + * Use `create(GetModChannelRequestSchema)` to create a new message. + */ +export const GetModChannelRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 0); + +/** + * @generated from message heimdallr.v1.UpdateModChannelRequest + */ +export type UpdateModChannelRequest = Message<"heimdallr.v1.UpdateModChannelRequest"> & { + /** + * @generated from field: heimdallr.v1.ModChannelSettings settings = 1; + */ + settings?: ModChannelSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateModChannelRequest. + * Use `create(UpdateModChannelRequestSchema)` to create a new message. + */ +export const UpdateModChannelRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 1); + +/** + * @generated from message heimdallr.v1.ModChannelSettings + */ +export type ModChannelSettings = Message<"heimdallr.v1.ModChannelSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: string moderator_channel = 2; + */ + moderatorChannel: string; +}; + +/** + * Describes the message heimdallr.v1.ModChannelSettings. + * Use `create(ModChannelSettingsSchema)` to create a new message. + */ +export const ModChannelSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 2); + +/** + * InfractionSettings + * + * @generated from message heimdallr.v1.GetInfractionSettingsRequest + */ +export type GetInfractionSettingsRequest = Message<"heimdallr.v1.GetInfractionSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetInfractionSettingsRequest. + * Use `create(GetInfractionSettingsRequestSchema)` to create a new message. + */ +export const GetInfractionSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 3); + +/** + * @generated from message heimdallr.v1.UpdateInfractionSettingsRequest + */ +export type UpdateInfractionSettingsRequest = Message<"heimdallr.v1.UpdateInfractionSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.InfractionSettings settings = 1; + */ + settings?: InfractionSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateInfractionSettingsRequest. + * Use `create(UpdateInfractionSettingsRequestSchema)` to create a new message. + */ +export const UpdateInfractionSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 4); + +/** + * @generated from message heimdallr.v1.InfractionSettings + */ +export type InfractionSettings = Message<"heimdallr.v1.InfractionSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: double half_life_days = 2; + */ + halfLifeDays: number; + + /** + * @generated from field: bool notify_on_warned_user_join = 3; + */ + notifyOnWarnedUserJoin: boolean; + + /** + * @generated from field: double notify_warn_severity_threshold = 4; + */ + notifyWarnSeverityThreshold: number; +}; + +/** + * Describes the message heimdallr.v1.InfractionSettings. + * Use `create(InfractionSettingsSchema)` to create a new message. + */ +export const InfractionSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 5); + +/** + * GatekeepSettings + * + * @generated from message heimdallr.v1.GetGatekeepSettingsRequest + */ +export type GetGatekeepSettingsRequest = Message<"heimdallr.v1.GetGatekeepSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetGatekeepSettingsRequest. + * Use `create(GetGatekeepSettingsRequestSchema)` to create a new message. + */ +export const GetGatekeepSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 6); + +/** + * @generated from message heimdallr.v1.UpdateGatekeepSettingsRequest + */ +export type UpdateGatekeepSettingsRequest = Message<"heimdallr.v1.UpdateGatekeepSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.GatekeepSettings settings = 1; + */ + settings?: GatekeepSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateGatekeepSettingsRequest. + * Use `create(UpdateGatekeepSettingsRequestSchema)` to create a new message. + */ +export const UpdateGatekeepSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 7); + +/** + * @generated from message heimdallr.v1.GatekeepSettings + */ +export type GatekeepSettings = Message<"heimdallr.v1.GatekeepSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: bool enabled = 2; + */ + enabled: boolean; + + /** + * @generated from field: string pending_role = 3; + */ + pendingRole: string; + + /** + * @generated from field: string approved_role = 4; + */ + approvedRole: string; + + /** + * @generated from field: bool add_pending_role_on_join = 5; + */ + addPendingRoleOnJoin: boolean; + + /** + * @generated from field: string approved_message = 6; + */ + approvedMessage: string; + + /** + * @generated from field: bool approved_message_v2 = 7; + */ + approvedMessageV2: boolean; + + /** + * @generated from field: string approved_message_v2_json = 8; + */ + approvedMessageV2Json: string; +}; + +/** + * Describes the message heimdallr.v1.GatekeepSettings. + * Use `create(GatekeepSettingsSchema)` to create a new message. + */ +export const GatekeepSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 8); + +/** + * JoinLeaveSettings + * + * @generated from message heimdallr.v1.GetJoinLeaveSettingsRequest + */ +export type GetJoinLeaveSettingsRequest = Message<"heimdallr.v1.GetJoinLeaveSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetJoinLeaveSettingsRequest. + * Use `create(GetJoinLeaveSettingsRequestSchema)` to create a new message. + */ +export const GetJoinLeaveSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 9); + +/** + * @generated from message heimdallr.v1.UpdateJoinLeaveSettingsRequest + */ +export type UpdateJoinLeaveSettingsRequest = Message<"heimdallr.v1.UpdateJoinLeaveSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.JoinLeaveSettings settings = 1; + */ + settings?: JoinLeaveSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateJoinLeaveSettingsRequest. + * Use `create(UpdateJoinLeaveSettingsRequestSchema)` to create a new message. + */ +export const UpdateJoinLeaveSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 10); + +/** + * @generated from message heimdallr.v1.JoinLeaveSettings + */ +export type JoinLeaveSettings = Message<"heimdallr.v1.JoinLeaveSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: bool join_message_enabled = 2; + */ + joinMessageEnabled: boolean; + + /** + * @generated from field: string join_message = 3; + */ + joinMessage: string; + + /** + * @generated from field: bool leave_message_enabled = 4; + */ + leaveMessageEnabled: boolean; + + /** + * @generated from field: string leave_message = 5; + */ + leaveMessage: string; + + /** + * @generated from field: string channel = 6; + */ + channel: string; + + /** + * @generated from field: bool join_message_v2 = 7; + */ + joinMessageV2: boolean; + + /** + * @generated from field: string join_message_v2_json = 8; + */ + joinMessageV2Json: string; + + /** + * @generated from field: bool leave_message_v2 = 9; + */ + leaveMessageV2: boolean; + + /** + * @generated from field: string leave_message_v2_json = 10; + */ + leaveMessageV2Json: string; +}; + +/** + * Describes the message heimdallr.v1.JoinLeaveSettings. + * Use `create(JoinLeaveSettingsSchema)` to create a new message. + */ +export const JoinLeaveSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 11); + +/** + * AntiSpamSettings + * + * @generated from message heimdallr.v1.GetAntiSpamSettingsRequest + */ +export type GetAntiSpamSettingsRequest = Message<"heimdallr.v1.GetAntiSpamSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetAntiSpamSettingsRequest. + * Use `create(GetAntiSpamSettingsRequestSchema)` to create a new message. + */ +export const GetAntiSpamSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 12); + +/** + * @generated from message heimdallr.v1.UpdateAntiSpamSettingsRequest + */ +export type UpdateAntiSpamSettingsRequest = Message<"heimdallr.v1.UpdateAntiSpamSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.AntiSpamSettings settings = 1; + */ + settings?: AntiSpamSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateAntiSpamSettingsRequest. + * Use `create(UpdateAntiSpamSettingsRequestSchema)` to create a new message. + */ +export const UpdateAntiSpamSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 13); + +/** + * @generated from message heimdallr.v1.AntiSpamSettings + */ +export type AntiSpamSettings = Message<"heimdallr.v1.AntiSpamSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: bool enabled = 2; + */ + enabled: boolean; + + /** + * @generated from field: int32 count = 3; + */ + count: number; + + /** + * @generated from field: int32 cooldown_seconds = 4; + */ + cooldownSeconds: number; +}; + +/** + * Describes the message heimdallr.v1.AntiSpamSettings. + * Use `create(AntiSpamSettingsSchema)` to create a new message. + */ +export const AntiSpamSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 14); + +/** + * BanFooterSettings + * + * @generated from message heimdallr.v1.GetBanFooterSettingsRequest + */ +export type GetBanFooterSettingsRequest = Message<"heimdallr.v1.GetBanFooterSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetBanFooterSettingsRequest. + * Use `create(GetBanFooterSettingsRequestSchema)` to create a new message. + */ +export const GetBanFooterSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 15); + +/** + * @generated from message heimdallr.v1.UpdateBanFooterSettingsRequest + */ +export type UpdateBanFooterSettingsRequest = Message<"heimdallr.v1.UpdateBanFooterSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.BanFooterSettings settings = 1; + */ + settings?: BanFooterSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateBanFooterSettingsRequest. + * Use `create(UpdateBanFooterSettingsRequestSchema)` to create a new message. + */ +export const UpdateBanFooterSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 16); + +/** + * @generated from message heimdallr.v1.BanFooterSettings + */ +export type BanFooterSettings = Message<"heimdallr.v1.BanFooterSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: string footer = 2; + */ + footer: string; + + /** + * @generated from field: bool always_send = 3; + */ + alwaysSend: boolean; +}; + +/** + * Describes the message heimdallr.v1.BanFooterSettings. + * Use `create(BanFooterSettingsSchema)` to create a new message. + */ +export const BanFooterSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 17); + +/** + * ModmailSettings + * + * @generated from message heimdallr.v1.GetModmailSettingsRequest + */ +export type GetModmailSettingsRequest = Message<"heimdallr.v1.GetModmailSettingsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.GetModmailSettingsRequest. + * Use `create(GetModmailSettingsRequestSchema)` to create a new message. + */ +export const GetModmailSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 18); + +/** + * @generated from message heimdallr.v1.UpdateModmailSettingsRequest + */ +export type UpdateModmailSettingsRequest = Message<"heimdallr.v1.UpdateModmailSettingsRequest"> & { + /** + * @generated from field: heimdallr.v1.ModmailSettings settings = 1; + */ + settings?: ModmailSettings; +}; + +/** + * Describes the message heimdallr.v1.UpdateModmailSettingsRequest. + * Use `create(UpdateModmailSettingsRequestSchema)` to create a new message. + */ +export const UpdateModmailSettingsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 19); + +/** + * @generated from message heimdallr.v1.ModmailSettings + */ +export type ModmailSettings = Message<"heimdallr.v1.ModmailSettings"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: string report_threads_channel = 2; + */ + reportThreadsChannel: string; + + /** + * @generated from field: string report_notification_channel = 3; + */ + reportNotificationChannel: string; + + /** + * @generated from field: string report_ping_role = 4; + */ + reportPingRole: string; +}; + +/** + * Describes the message heimdallr.v1.ModmailSettings. + * Use `create(ModmailSettingsSchema)` to create a new message. + */ +export const ModmailSettingsSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 20); + +/** + * Guild data (channels & roles) + * + * @generated from message heimdallr.v1.Channel + */ +export type Channel = Message<"heimdallr.v1.Channel"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string name = 2; + */ + name: string; + + /** + * @generated from field: int32 type = 3; + */ + type: number; + + /** + * @generated from field: int32 position = 4; + */ + position: number; + + /** + * @generated from field: string parent_id = 5; + */ + parentId: string; +}; + +/** + * Describes the message heimdallr.v1.Channel. + * Use `create(ChannelSchema)` to create a new message. + */ +export const ChannelSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 21); + +/** + * @generated from message heimdallr.v1.Role + */ +export type Role = Message<"heimdallr.v1.Role"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string name = 2; + */ + name: string; + + /** + * @generated from field: int32 color = 3; + */ + color: number; + + /** + * @generated from field: int32 position = 4; + */ + position: number; + + /** + * @generated from field: bool managed = 5; + */ + managed: boolean; +}; + +/** + * Describes the message heimdallr.v1.Role. + * Use `create(RoleSchema)` to create a new message. + */ +export const RoleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 22); + +/** + * @generated from message heimdallr.v1.ListChannelsRequest + */ +export type ListChannelsRequest = Message<"heimdallr.v1.ListChannelsRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.ListChannelsRequest. + * Use `create(ListChannelsRequestSchema)` to create a new message. + */ +export const ListChannelsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 23); + +/** + * @generated from message heimdallr.v1.ListChannelsResponse + */ +export type ListChannelsResponse = Message<"heimdallr.v1.ListChannelsResponse"> & { + /** + * @generated from field: repeated heimdallr.v1.Channel channels = 1; + */ + channels: Channel[]; +}; + +/** + * Describes the message heimdallr.v1.ListChannelsResponse. + * Use `create(ListChannelsResponseSchema)` to create a new message. + */ +export const ListChannelsResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 24); + +/** + * @generated from message heimdallr.v1.ListRolesRequest + */ +export type ListRolesRequest = Message<"heimdallr.v1.ListRolesRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; +}; + +/** + * Describes the message heimdallr.v1.ListRolesRequest. + * Use `create(ListRolesRequestSchema)` to create a new message. + */ +export const ListRolesRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 25); + +/** + * @generated from message heimdallr.v1.ListRolesResponse + */ +export type ListRolesResponse = Message<"heimdallr.v1.ListRolesResponse"> & { + /** + * @generated from field: repeated heimdallr.v1.Role roles = 1; + */ + roles: Role[]; +}; + +/** + * Describes the message heimdallr.v1.ListRolesResponse. + * Use `create(ListRolesResponseSchema)` to create a new message. + */ +export const ListRolesResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 26); + +/** + * SendComponentsMessage + * + * @generated from message heimdallr.v1.SendComponentsMessageRequest + */ +export type SendComponentsMessageRequest = Message<"heimdallr.v1.SendComponentsMessageRequest"> & { + /** + * @generated from field: string guild_id = 1; + */ + guildId: string; + + /** + * @generated from field: string channel_id = 2; + */ + channelId: string; + + /** + * JSON array of discord LayoutComponents + * + * @generated from field: string components_json = 3; + */ + componentsJson: string; +}; + +/** + * Describes the message heimdallr.v1.SendComponentsMessageRequest. + * Use `create(SendComponentsMessageRequestSchema)` to create a new message. + */ +export const SendComponentsMessageRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 27); + +/** + * @generated from message heimdallr.v1.SendComponentsMessageResponse + */ +export type SendComponentsMessageResponse = Message<"heimdallr.v1.SendComponentsMessageResponse"> & { + /** + * @generated from field: string message_id = 1; + */ + messageId: string; +}; + +/** + * Describes the message heimdallr.v1.SendComponentsMessageResponse. + * Use `create(SendComponentsMessageResponseSchema)` to create a new message. + */ +export const SendComponentsMessageResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 28); + +/** + * Template placeholders + * + * @generated from message heimdallr.v1.TemplatePlaceholder + */ +export type TemplatePlaceholder = Message<"heimdallr.v1.TemplatePlaceholder"> & { + /** + * @generated from field: string placeholder = 1; + */ + placeholder: string; + + /** + * @generated from field: string description = 2; + */ + description: string; +}; + +/** + * Describes the message heimdallr.v1.TemplatePlaceholder. + * Use `create(TemplatePlaceholderSchema)` to create a new message. + */ +export const TemplatePlaceholderSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 29); + +/** + * @generated from message heimdallr.v1.GetTemplatePlaceholdersRequest + */ +export type GetTemplatePlaceholdersRequest = Message<"heimdallr.v1.GetTemplatePlaceholdersRequest"> & { +}; + +/** + * Describes the message heimdallr.v1.GetTemplatePlaceholdersRequest. + * Use `create(GetTemplatePlaceholdersRequestSchema)` to create a new message. + */ +export const GetTemplatePlaceholdersRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 30); + +/** + * @generated from message heimdallr.v1.GetTemplatePlaceholdersResponse + */ +export type GetTemplatePlaceholdersResponse = Message<"heimdallr.v1.GetTemplatePlaceholdersResponse"> & { + /** + * @generated from field: repeated heimdallr.v1.TemplatePlaceholder placeholders = 1; + */ + placeholders: TemplatePlaceholder[]; +}; + +/** + * Describes the message heimdallr.v1.GetTemplatePlaceholdersResponse. + * Use `create(GetTemplatePlaceholdersResponseSchema)` to create a new message. + */ +export const GetTemplatePlaceholdersResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_heimdallr_v1_guild_settings, 31); + +/** + * @generated from service heimdallr.v1.GuildSettingsService + */ +export const GuildSettingsService: GenService<{ + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetModChannel + */ + getModChannel: { + methodKind: "unary"; + input: typeof GetModChannelRequestSchema; + output: typeof ModChannelSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateModChannel + */ + updateModChannel: { + methodKind: "unary"; + input: typeof UpdateModChannelRequestSchema; + output: typeof ModChannelSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetInfractionSettings + */ + getInfractionSettings: { + methodKind: "unary"; + input: typeof GetInfractionSettingsRequestSchema; + output: typeof InfractionSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateInfractionSettings + */ + updateInfractionSettings: { + methodKind: "unary"; + input: typeof UpdateInfractionSettingsRequestSchema; + output: typeof InfractionSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetGatekeepSettings + */ + getGatekeepSettings: { + methodKind: "unary"; + input: typeof GetGatekeepSettingsRequestSchema; + output: typeof GatekeepSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateGatekeepSettings + */ + updateGatekeepSettings: { + methodKind: "unary"; + input: typeof UpdateGatekeepSettingsRequestSchema; + output: typeof GatekeepSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetJoinLeaveSettings + */ + getJoinLeaveSettings: { + methodKind: "unary"; + input: typeof GetJoinLeaveSettingsRequestSchema; + output: typeof JoinLeaveSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateJoinLeaveSettings + */ + updateJoinLeaveSettings: { + methodKind: "unary"; + input: typeof UpdateJoinLeaveSettingsRequestSchema; + output: typeof JoinLeaveSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetAntiSpamSettings + */ + getAntiSpamSettings: { + methodKind: "unary"; + input: typeof GetAntiSpamSettingsRequestSchema; + output: typeof AntiSpamSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateAntiSpamSettings + */ + updateAntiSpamSettings: { + methodKind: "unary"; + input: typeof UpdateAntiSpamSettingsRequestSchema; + output: typeof AntiSpamSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetBanFooterSettings + */ + getBanFooterSettings: { + methodKind: "unary"; + input: typeof GetBanFooterSettingsRequestSchema; + output: typeof BanFooterSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateBanFooterSettings + */ + updateBanFooterSettings: { + methodKind: "unary"; + input: typeof UpdateBanFooterSettingsRequestSchema; + output: typeof BanFooterSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetModmailSettings + */ + getModmailSettings: { + methodKind: "unary"; + input: typeof GetModmailSettingsRequestSchema; + output: typeof ModmailSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.UpdateModmailSettings + */ + updateModmailSettings: { + methodKind: "unary"; + input: typeof UpdateModmailSettingsRequestSchema; + output: typeof ModmailSettingsSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.ListChannels + */ + listChannels: { + methodKind: "unary"; + input: typeof ListChannelsRequestSchema; + output: typeof ListChannelsResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.ListRoles + */ + listRoles: { + methodKind: "unary"; + input: typeof ListRolesRequestSchema; + output: typeof ListRolesResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.GetTemplatePlaceholders + */ + getTemplatePlaceholders: { + methodKind: "unary"; + input: typeof GetTemplatePlaceholdersRequestSchema; + output: typeof GetTemplatePlaceholdersResponseSchema; + }, + /** + * @generated from rpc heimdallr.v1.GuildSettingsService.SendComponentsMessage + */ + sendComponentsMessage: { + methodKind: "unary"; + input: typeof SendComponentsMessageRequestSchema; + output: typeof SendComponentsMessageResponseSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_heimdallr_v1_guild_settings, 0); + diff --git a/web-dashboard/src/lib/api/client.ts b/web-dashboard/src/lib/api/client.ts new file mode 100644 index 0000000..069146d --- /dev/null +++ b/web-dashboard/src/lib/api/client.ts @@ -0,0 +1,7 @@ +import { createClient } from "@connectrpc/connect"; +import { transport } from "./transport"; +import { AuthService } from "../../gen/heimdallr/v1/auth_pb"; +import { GuildSettingsService } from "../../gen/heimdallr/v1/guild_settings_pb"; + +export const authClient = createClient(AuthService, transport); +export const settingsClient = createClient(GuildSettingsService, transport); diff --git a/web-dashboard/src/lib/api/transport.ts b/web-dashboard/src/lib/api/transport.ts new file mode 100644 index 0000000..fe98ef6 --- /dev/null +++ b/web-dashboard/src/lib/api/transport.ts @@ -0,0 +1,6 @@ +import { createConnectTransport } from "@connectrpc/connect-web"; + +export const transport = createConnectTransport({ + baseUrl: "/", + credentials: "include", +}); diff --git a/web-dashboard/src/lib/auth/auth.ts b/web-dashboard/src/lib/auth/auth.ts new file mode 100644 index 0000000..a3879c3 --- /dev/null +++ b/web-dashboard/src/lib/auth/auth.ts @@ -0,0 +1,5 @@ +import { userStore } from "../stores/user.svelte"; + +export function isLoggedIn(): boolean { + return userStore().isLoggedIn; +} diff --git a/web-dashboard/src/lib/components/layout/Layout.svelte b/web-dashboard/src/lib/components/layout/Layout.svelte new file mode 100644 index 0000000..537a6e8 --- /dev/null +++ b/web-dashboard/src/lib/components/layout/Layout.svelte @@ -0,0 +1,25 @@ + + +
    + +
    + {#if showSidebar} + + {/if} +
    + {@render children()} +
    +
    +
    diff --git a/web-dashboard/src/lib/components/layout/Navbar.svelte b/web-dashboard/src/lib/components/layout/Navbar.svelte new file mode 100644 index 0000000..f1b2718 --- /dev/null +++ b/web-dashboard/src/lib/components/layout/Navbar.svelte @@ -0,0 +1,79 @@ + + + diff --git a/web-dashboard/src/lib/components/layout/Sidebar.svelte b/web-dashboard/src/lib/components/layout/Sidebar.svelte new file mode 100644 index 0000000..6ae774e --- /dev/null +++ b/web-dashboard/src/lib/components/layout/Sidebar.svelte @@ -0,0 +1,18 @@ + + + diff --git a/web-dashboard/src/lib/components/sandbox/ActionRowEditor.svelte b/web-dashboard/src/lib/components/sandbox/ActionRowEditor.svelte new file mode 100644 index 0000000..381b757 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/ActionRowEditor.svelte @@ -0,0 +1,80 @@ + + +
    + Buttons + {#each node.buttons as btn, i} +
    +
    + + + {#if node.buttons.length > 1} + + {/if} +
    +
    + {#if btn.style === "link"} + + {:else} + + {/if} + +
    +
    + {/each} + {#if node.buttons.length < 5} + + {/if} +
    diff --git a/web-dashboard/src/lib/components/sandbox/ComponentEditor.svelte b/web-dashboard/src/lib/components/sandbox/ComponentEditor.svelte new file mode 100644 index 0000000..a010318 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/ComponentEditor.svelte @@ -0,0 +1,29 @@ + + +{#if node.type === "text_display"} + +{:else if node.type === "section"} + +{:else if node.type === "container"} + +{:else if node.type === "separator"} + +{:else if node.type === "media_gallery"} + +{:else if node.type === "action_row"} + +{/if} diff --git a/web-dashboard/src/lib/components/sandbox/ContainerEditor.svelte b/web-dashboard/src/lib/components/sandbox/ContainerEditor.svelte new file mode 100644 index 0000000..49933ee --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/ContainerEditor.svelte @@ -0,0 +1,91 @@ + + +
    +
    + + +
    + +
    + Children + {#each node.children as child, i} +
    +
    + {child.type.replace("_", " ")} +
    + + + +
    +
    + +
    + {/each} + + +
    +
    diff --git a/web-dashboard/src/lib/components/sandbox/MediaGalleryEditor.svelte b/web-dashboard/src/lib/components/sandbox/MediaGalleryEditor.svelte new file mode 100644 index 0000000..26f4903 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/MediaGalleryEditor.svelte @@ -0,0 +1,45 @@ + + +
    + Media Items + {#each node.items as item, i} +
    + + + {#if node.items.length > 1} + + {/if} +
    + {/each} + {#if node.items.length < 10} + + {/if} +
    diff --git a/web-dashboard/src/lib/components/sandbox/MessageBuilder.svelte b/web-dashboard/src/lib/components/sandbox/MessageBuilder.svelte new file mode 100644 index 0000000..fb486a4 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/MessageBuilder.svelte @@ -0,0 +1,94 @@ + + +
    + {#each components as node, i} +
    +
    +
    + {node.type.replace("_", " ")} +
    + + + +
    +
    + +
    +
    + {/each} + + {#if components.length === 0} +
    + No components yet. Add one below to get started. +
    + {/if} + + +
    diff --git a/web-dashboard/src/lib/components/sandbox/MessagePreview.svelte b/web-dashboard/src/lib/components/sandbox/MessagePreview.svelte new file mode 100644 index 0000000..eae1e25 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/MessagePreview.svelte @@ -0,0 +1,113 @@ + + +{#snippet previewNode(node: ComponentNode)} + {#if node.type === "text_display"} +
    {node.content || "\u00A0"}
    + {:else if node.type === "section"} +
    +
    + {#each node.texts.filter((t) => t.trim()) as text} +
    {text}
    + {/each} +
    + {#if node.accessory?.kind === "thumbnail" && node.accessory.url} + Thumbnail { (e.currentTarget as HTMLImageElement).style.display = "none"; }} + /> + {:else if node.accessory?.kind === "button"} + + {/if} +
    + {:else if node.type === "container"} +
    +
    + {#each node.children as child} + {@render previewNode(child)} + {/each} +
    +
    + {:else if node.type === "separator"} + {#if node.divider} +
    + {:else} +
    + {/if} + {:else if node.type === "media_gallery"} +
    + {#each node.items.filter((i) => i.url.trim()) as item} +
    + {item.description { + const el = e.currentTarget as HTMLImageElement; + el.style.display = "none"; + el.nextElementSibling?.classList.remove("hidden"); + }} + /> + +
    + {/each} +
    + {:else if node.type === "action_row"} +
    + {#each node.buttons.filter((b) => b.label.trim()) as btn} + + {/each} +
    + {/if} +{/snippet} + +
    +
    +

    Preview

    + {#if components.length === 0} +
    Nothing to preview
    + {:else} +
    + {#each components as node} + {@render previewNode(node)} + {/each} +
    + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/sandbox/SectionEditor.svelte b/web-dashboard/src/lib/components/sandbox/SectionEditor.svelte new file mode 100644 index 0000000..425ef35 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/SectionEditor.svelte @@ -0,0 +1,104 @@ + + +
    +
    + Text Fields + {#each node.texts as _, i} +
    + + {#if node.texts.length > 1} + + {/if} +
    + {/each} + {#if node.texts.length < 3} + + {/if} +
    + +
    + Accessory + + + {#if node.accessory?.kind === "thumbnail"} + + {:else if node.accessory?.kind === "button"} +
    + + +
    + + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/sandbox/SeparatorEditor.svelte b/web-dashboard/src/lib/components/sandbox/SeparatorEditor.svelte new file mode 100644 index 0000000..05584dd --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/SeparatorEditor.svelte @@ -0,0 +1,23 @@ + + +
    + + +
    diff --git a/web-dashboard/src/lib/components/sandbox/TextDisplayEditor.svelte b/web-dashboard/src/lib/components/sandbox/TextDisplayEditor.svelte new file mode 100644 index 0000000..7f30b7a --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/TextDisplayEditor.svelte @@ -0,0 +1,19 @@ + + +
    + Markdown Content + +
    diff --git a/web-dashboard/src/lib/components/sandbox/serialize.ts b/web-dashboard/src/lib/components/sandbox/serialize.ts new file mode 100644 index 0000000..22877a3 --- /dev/null +++ b/web-dashboard/src/lib/components/sandbox/serialize.ts @@ -0,0 +1,381 @@ +// Discord component type constants +const COMPONENT_TYPE = { + action_row: 1, + button: 2, + string_select: 3, + text_input: 4, + user_select: 5, + role_select: 6, + mentionable_select: 7, + channel_select: 8, + section: 9, + text_display: 10, + thumbnail: 11, + media_gallery: 12, + file: 13, + separator: 14, + container: 17, +} as const; + +const BUTTON_STYLE = { + primary: 1, + secondary: 2, + success: 3, + danger: 4, + link: 5, +} as const; + +export type ButtonStyle = keyof typeof BUTTON_STYLE; + +export interface ButtonNode { + label: string; + style: ButtonStyle; + customId?: string; + url?: string; + emoji?: string; +} + +export type ComponentNode = + | { type: "text_display"; content: string } + | { + type: "section"; + texts: string[]; + accessory?: + | { kind: "thumbnail"; url: string } + | { + kind: "button"; + label: string; + style: ButtonStyle; + customId: string; + url?: string; + emoji?: string; + }; + } + | { + type: "container"; + accentColor: string; + spoiler: boolean; + children: ComponentNode[]; + } + | { + type: "separator"; + spacing: "small" | "large"; + divider: boolean; + } + | { + type: "media_gallery"; + items: { url: string; description?: string }[]; + } + | { type: "action_row"; buttons: ButtonNode[] }; + +function serializeButton(btn: ButtonNode): Record { + const obj: Record = { + type: COMPONENT_TYPE.button, + style: BUTTON_STYLE[btn.style], + label: btn.label, + }; + if (btn.style === "link" && btn.url) { + obj.url = btn.url; + } else if (btn.customId) { + obj.custom_id = btn.customId; + } + if (btn.emoji) { + // Custom emoji: <:name:id> or + const customMatch = btn.emoji.match(/^<(a?):(\w+):(\d+)>$/); + if (customMatch) { + obj.emoji = { name: customMatch[2], id: customMatch[3] }; + } else { + // Unicode emoji + obj.emoji = { name: btn.emoji }; + } + } + return obj; +} + +function hexToDecimal(hex: string): number | undefined { + if (!hex || hex === "#000000" || hex === "") return undefined; + const clean = hex.replace("#", ""); + const num = parseInt(clean, 16); + return isNaN(num) ? undefined : num; +} + +function serializeComponent( + node: ComponentNode, +): Record | null { + switch (node.type) { + case "text_display": + return { + type: COMPONENT_TYPE.text_display, + content: node.content, + }; + + case "section": { + const components = node.texts + .filter((t) => t.trim()) + .map((t) => ({ + type: COMPONENT_TYPE.text_display, + content: t, + })); + + if (components.length === 0) return null; + + const obj: Record = { + type: COMPONENT_TYPE.section, + components, + }; + + if (node.accessory) { + if (node.accessory.kind === "thumbnail") { + obj.accessory = { + type: COMPONENT_TYPE.thumbnail, + media: { url: node.accessory.url }, + }; + } else if (node.accessory.kind === "button") { + obj.accessory = serializeButton({ + label: node.accessory.label, + style: node.accessory.style, + customId: node.accessory.customId, + url: node.accessory.url, + emoji: node.accessory.emoji, + }); + } + } + + return obj; + } + + case "container": { + const children = node.children + .map(serializeComponent) + .filter((c): c is Record => c !== null); + + if (children.length === 0) return null; + + const obj: Record = { + type: COMPONENT_TYPE.container, + components: children, + }; + + const color = hexToDecimal(node.accentColor); + if (color !== undefined) { + obj.accent_color = color; + } + if (node.spoiler) { + obj.spoiler = true; + } + + return obj; + } + + case "separator": + return { + type: COMPONENT_TYPE.separator, + spacing: node.spacing === "large" ? 2 : 1, + divider: node.divider, + }; + + case "media_gallery": { + const items = node.items + .filter((i) => i.url.trim()) + .map((i) => { + const item: Record = { + media: { url: i.url }, + }; + if (i.description) { + item.description = i.description; + } + return item; + }); + + if (items.length === 0) return null; + + return { + type: COMPONENT_TYPE.media_gallery, + items, + }; + } + + case "action_row": { + const components = node.buttons + .filter((b) => b.label.trim()) + .map(serializeButton); + + if (components.length === 0) return null; + + return { + type: COMPONENT_TYPE.action_row, + components, + }; + } + + default: + return null; + } +} + +const BUTTON_STYLE_REVERSE: Record = { + 1: "primary", + 2: "secondary", + 3: "success", + 4: "danger", + 5: "link", +}; + +function decimalToHex(num: number | undefined): string { + if (num === undefined || num === 0) return ""; + return "#" + num.toString(16).padStart(6, "0"); +} + +function deserializeButton(obj: Record): ButtonNode { + const style = BUTTON_STYLE_REVERSE[(obj.style as number) ?? 1] ?? "primary"; + const btn: ButtonNode = { + label: (obj.label as string) ?? "", + style, + }; + if (obj.custom_id) btn.customId = obj.custom_id as string; + if (obj.url) btn.url = obj.url as string; + if (obj.emoji) { + const emoji = obj.emoji as Record; + if (emoji.id) { + btn.emoji = `<:${emoji.name}:${emoji.id}>`; + } else if (emoji.name) { + btn.emoji = emoji.name as string; + } + } + return btn; +} + +function deserializeComponent(obj: Record): ComponentNode | null { + const type = obj.type as number; + + switch (type) { + case COMPONENT_TYPE.text_display: + return { type: "text_display", content: (obj.content as string) ?? "" }; + + case COMPONENT_TYPE.section: { + const components = (obj.components as Record[]) ?? []; + const texts = components + .filter((c) => (c.type as number) === COMPONENT_TYPE.text_display) + .map((c) => (c.content as string) ?? ""); + if (texts.length === 0) texts.push(""); + + const node: ComponentNode = { type: "section", texts }; + + if (obj.accessory) { + const acc = obj.accessory as Record; + if ((acc.type as number) === COMPONENT_TYPE.thumbnail) { + const media = acc.media as Record | undefined; + (node as any).accessory = { + kind: "thumbnail", + url: (media?.url as string) ?? "", + }; + } else if ((acc.type as number) === COMPONENT_TYPE.button) { + const btn = deserializeButton(acc); + (node as any).accessory = { + kind: "button", + label: btn.label, + style: btn.style, + customId: btn.customId ?? "", + url: btn.url, + emoji: btn.emoji, + }; + } + } + + return node; + } + + case COMPONENT_TYPE.container: { + const children = ((obj.components as Record[]) ?? []) + .map(deserializeComponent) + .filter((c): c is ComponentNode => c !== null); + + return { + type: "container", + accentColor: decimalToHex(obj.accent_color as number | undefined), + spoiler: (obj.spoiler as boolean) ?? false, + children, + }; + } + + case COMPONENT_TYPE.separator: + return { + type: "separator", + spacing: (obj.spacing as number) === 2 ? "large" : "small", + divider: (obj.divider as boolean) ?? true, + }; + + case COMPONENT_TYPE.media_gallery: { + const items = ((obj.items as Record[]) ?? []).map((item) => { + const media = item.media as Record | undefined; + return { + url: (media?.url as string) ?? "", + description: item.description as string | undefined, + }; + }); + if (items.length === 0) items.push({ url: "" }); + return { type: "media_gallery", items }; + } + + case COMPONENT_TYPE.action_row: { + const components = (obj.components as Record[]) ?? []; + const buttons = components + .filter((c) => (c.type as number) === COMPONENT_TYPE.button) + .map(deserializeButton); + if (buttons.length === 0) return null; + return { type: "action_row", buttons }; + } + + default: + return null; + } +} + +export function deserializeComponents(json: string): ComponentNode[] { + if (!json) return []; + try { + const parsed = JSON.parse(json) as Record[]; + if (!Array.isArray(parsed)) return []; + return parsed + .map(deserializeComponent) + .filter((c): c is ComponentNode => c !== null); + } catch { + return []; + } +} + +export function serializeComponents(nodes: ComponentNode[]): string { + const result = nodes + .map(serializeComponent) + .filter((c): c is Record => c !== null); + return JSON.stringify(result); +} + +export function createDefaultNode( + type: ComponentNode["type"], +): ComponentNode { + switch (type) { + case "text_display": + return { type: "text_display", content: "" }; + case "section": + return { type: "section", texts: [""], accessory: undefined }; + case "container": + return { + type: "container", + accentColor: "", + spoiler: false, + children: [], + }; + case "separator": + return { type: "separator", spacing: "small", divider: true }; + case "media_gallery": + return { type: "media_gallery", items: [{ url: "" }] }; + case "action_row": + return { + type: "action_row", + buttons: [ + { label: "Button", style: "primary", customId: "btn_1" }, + ], + }; + } +} diff --git a/web-dashboard/src/lib/components/settings/AntiSpamSection.svelte b/web-dashboard/src/lib/components/settings/AntiSpamSection.svelte new file mode 100644 index 0000000..17715cd --- /dev/null +++ b/web-dashboard/src/lib/components/settings/AntiSpamSection.svelte @@ -0,0 +1,58 @@ + + +
    +
    +

    Anti-Spam

    +

    + Automatically detect and act on spam messages. +

    +
    + + {#if section.loading} + + {:else} + (section.data.enabled = v)} + /> + + (section.data.count = v)} + /> + + (section.data.cooldownSeconds = v)} + /> + + settings.saveAntiSpam()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/settings/BanFooterSection.svelte b/web-dashboard/src/lib/components/settings/BanFooterSection.svelte new file mode 100644 index 0000000..1cc5107 --- /dev/null +++ b/web-dashboard/src/lib/components/settings/BanFooterSection.svelte @@ -0,0 +1,47 @@ + + + diff --git a/web-dashboard/src/lib/components/settings/GatekeepSection.svelte b/web-dashboard/src/lib/components/settings/GatekeepSection.svelte new file mode 100644 index 0000000..9c149cf --- /dev/null +++ b/web-dashboard/src/lib/components/settings/GatekeepSection.svelte @@ -0,0 +1,86 @@ + + +
    +
    +

    Gatekeep

    +

    + Member verification system. New members get a pending role and must be approved to access the server. +

    +
    + + {#if section.loading} + + {:else} + (section.data.enabled = v)} + /> + + (section.data.pendingRole = v)} + /> + + (section.data.approvedRole = v)} + /> + + (section.data.addPendingRoleOnJoin = v)} + /> + + (section.data.approvedMessage = v)} + onV2EnabledChange={(v) => (section.data.approvedMessageV2 = v)} + onV2JsonChange={(v) => (section.data.approvedMessageV2Json = v)} + /> + + settings.saveGatekeep()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/settings/InfractionsSection.svelte b/web-dashboard/src/lib/components/settings/InfractionsSection.svelte new file mode 100644 index 0000000..fec61e1 --- /dev/null +++ b/web-dashboard/src/lib/components/settings/InfractionsSection.svelte @@ -0,0 +1,58 @@ + + +
    +
    +

    Infractions

    +

    + Configure infraction severity decay and join notifications for warned users. +

    +
    + + {#if section.loading} + + {:else} + (section.data.halfLifeDays = v)} + /> + + (section.data.notifyOnWarnedUserJoin = v)} + /> + + (section.data.notifyWarnSeverityThreshold = v)} + /> + + settings.saveInfractions()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/settings/JoinLeaveSection.svelte b/web-dashboard/src/lib/components/settings/JoinLeaveSection.svelte new file mode 100644 index 0000000..3ea7564 --- /dev/null +++ b/web-dashboard/src/lib/components/settings/JoinLeaveSection.svelte @@ -0,0 +1,90 @@ + + +
    +
    +

    Join/Leave Messages

    +

    + Configure messages sent when members join or leave the server. +

    +
    + + {#if section.loading} + + {:else} + (section.data.channel = v)} + /> + +
    Join Message
    + + (section.data.joinMessageEnabled = v)} + /> + + (section.data.joinMessage = v)} + onV2EnabledChange={(v) => (section.data.joinMessageV2 = v)} + onV2JsonChange={(v) => (section.data.joinMessageV2Json = v)} + /> + +
    Leave Message
    + + (section.data.leaveMessageEnabled = v)} + /> + + (section.data.leaveMessage = v)} + onV2EnabledChange={(v) => (section.data.leaveMessageV2 = v)} + onV2JsonChange={(v) => (section.data.leaveMessageV2Json = v)} + /> + + settings.saveJoinLeave()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/settings/ModChannelSection.svelte b/web-dashboard/src/lib/components/settings/ModChannelSection.svelte new file mode 100644 index 0000000..225883e --- /dev/null +++ b/web-dashboard/src/lib/components/settings/ModChannelSection.svelte @@ -0,0 +1,39 @@ + + +
    +
    +

    Moderator Channel

    +

    + The channel where bot notifications and moderator information are sent. +

    +
    + + {#if section.loading} + + {:else} + (section.data.moderatorChannel = v)} + /> + settings.saveModChannel()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/settings/ModmailSection.svelte b/web-dashboard/src/lib/components/settings/ModmailSection.svelte new file mode 100644 index 0000000..90f8bb4 --- /dev/null +++ b/web-dashboard/src/lib/components/settings/ModmailSection.svelte @@ -0,0 +1,57 @@ + + +
    +
    +

    Modmail

    +

    + Configure channels and roles for the modmail report system. +

    +
    + + {#if section.loading} + + {:else} + (section.data.reportThreadsChannel = v)} + /> + + (section.data.reportNotificationChannel = v)} + /> + + (section.data.reportPingRole = v)} + /> + + settings.saveModmail()} + /> + {/if} +
    +
    diff --git a/web-dashboard/src/lib/components/ui/ChannelSelect.svelte b/web-dashboard/src/lib/components/ui/ChannelSelect.svelte new file mode 100644 index 0000000..6096f17 --- /dev/null +++ b/web-dashboard/src/lib/components/ui/ChannelSelect.svelte @@ -0,0 +1,137 @@ + + + diff --git a/web-dashboard/src/lib/components/ui/NumberField.svelte b/web-dashboard/src/lib/components/ui/NumberField.svelte new file mode 100644 index 0000000..412be33 --- /dev/null +++ b/web-dashboard/src/lib/components/ui/NumberField.svelte @@ -0,0 +1,31 @@ + + + diff --git a/web-dashboard/src/lib/components/ui/RoleSelect.svelte b/web-dashboard/src/lib/components/ui/RoleSelect.svelte new file mode 100644 index 0000000..a3deb2b --- /dev/null +++ b/web-dashboard/src/lib/components/ui/RoleSelect.svelte @@ -0,0 +1,50 @@ + + + diff --git a/web-dashboard/src/lib/components/ui/SaveButton.svelte b/web-dashboard/src/lib/components/ui/SaveButton.svelte new file mode 100644 index 0000000..1d4a0ff --- /dev/null +++ b/web-dashboard/src/lib/components/ui/SaveButton.svelte @@ -0,0 +1,28 @@ + + +
    + + {#if error} + {error} + {/if} +
    diff --git a/web-dashboard/src/lib/components/ui/SnowflakeField.svelte b/web-dashboard/src/lib/components/ui/SnowflakeField.svelte new file mode 100644 index 0000000..666922a --- /dev/null +++ b/web-dashboard/src/lib/components/ui/SnowflakeField.svelte @@ -0,0 +1,27 @@ + + + diff --git a/web-dashboard/src/lib/components/ui/TextareaField.svelte b/web-dashboard/src/lib/components/ui/TextareaField.svelte new file mode 100644 index 0000000..41e58f7 --- /dev/null +++ b/web-dashboard/src/lib/components/ui/TextareaField.svelte @@ -0,0 +1,44 @@ + + +
    +
    + {label} + {#if description} + {description} + {/if} +
    + + {#if helpText} + + {#if showHelp} +
    +
    {helpText}
    +
    + {/if} + {/if} +
    diff --git a/web-dashboard/src/lib/components/ui/ToggleField.svelte b/web-dashboard/src/lib/components/ui/ToggleField.svelte new file mode 100644 index 0000000..f4a67d2 --- /dev/null +++ b/web-dashboard/src/lib/components/ui/ToggleField.svelte @@ -0,0 +1,25 @@ + + + diff --git a/web-dashboard/src/lib/components/ui/V2MessageToggle.svelte b/web-dashboard/src/lib/components/ui/V2MessageToggle.svelte new file mode 100644 index 0000000..aa7c61a --- /dev/null +++ b/web-dashboard/src/lib/components/ui/V2MessageToggle.svelte @@ -0,0 +1,116 @@ + + +
    +
    + {label} + {#if description} + {description} + {/if} +
    + + + + {#if v2Enabled} +
    + + {componentCount()} component{componentCount() !== 1 ? "s" : ""} configured + + +
    + {:else} + + {/if} +
    + + + + + diff --git a/web-dashboard/src/lib/routes/Callback.svelte b/web-dashboard/src/lib/routes/Callback.svelte new file mode 100644 index 0000000..4be72b2 --- /dev/null +++ b/web-dashboard/src/lib/routes/Callback.svelte @@ -0,0 +1,46 @@ + + +
    + {#if error} +
    +
    + {error} +
    + Back to Login +
    + {:else} +
    + +

    Logging in...

    +
    + {/if} +
    diff --git a/web-dashboard/src/lib/routes/Dashboard.svelte b/web-dashboard/src/lib/routes/Dashboard.svelte new file mode 100644 index 0000000..f61a2e7 --- /dev/null +++ b/web-dashboard/src/lib/routes/Dashboard.svelte @@ -0,0 +1,63 @@ + + + + {#if loading} +
    + +
    + {:else} +
    + {#each sections as sec} + {@const Component = sec.component} + + {/each} +
    + {/if} +
    diff --git a/web-dashboard/src/lib/routes/GuildSelector.svelte b/web-dashboard/src/lib/routes/GuildSelector.svelte new file mode 100644 index 0000000..88bbb70 --- /dev/null +++ b/web-dashboard/src/lib/routes/GuildSelector.svelte @@ -0,0 +1,90 @@ + + + +
    +

    Select a Server

    + + {#if error} +
    + {error} +
    + {/if} + + {#if guilds.loading} +
    + +
    + {:else if guilds.guilds.length === 0} +
    +

    + No servers found. Make sure you have admin permissions in a server where Heimdallr is installed. +

    +
    + {:else} + + {/if} +
    +
    diff --git a/web-dashboard/src/lib/routes/Login.svelte b/web-dashboard/src/lib/routes/Login.svelte new file mode 100644 index 0000000..48d2948 --- /dev/null +++ b/web-dashboard/src/lib/routes/Login.svelte @@ -0,0 +1,33 @@ + + +
    +
    +
    +

    Heimdallr

    +

    + Manage your Discord server settings from the web. +

    +
    +
    +

    How to log in

    +

    + Use the /admin-dashboard command in a + Discord server where Heimdallr is installed to get a login link. +

    +
    +
    +
    +
    +
    diff --git a/web-dashboard/src/lib/routes/Sandbox.svelte b/web-dashboard/src/lib/routes/Sandbox.svelte new file mode 100644 index 0000000..3ffa9ec --- /dev/null +++ b/web-dashboard/src/lib/routes/Sandbox.svelte @@ -0,0 +1,136 @@ + + + + {#if loading} +
    + +
    + {:else} +
    + +
    +

    Components V2 Builder

    + +
    + + +
    + + +
    +
    +

    Send

    + (channelId = v)} + /> + + {#if statusMessage} +
    + {statusMessage} +
    + {/if} +
    +
    +
    +
    + {/if} +
    diff --git a/web-dashboard/src/lib/sections.ts b/web-dashboard/src/lib/sections.ts new file mode 100644 index 0000000..689c1c7 --- /dev/null +++ b/web-dashboard/src/lib/sections.ts @@ -0,0 +1,24 @@ +import type { Component } from "svelte"; +import ModChannelSection from "./components/settings/ModChannelSection.svelte"; +import InfractionsSection from "./components/settings/InfractionsSection.svelte"; +import GatekeepSection from "./components/settings/GatekeepSection.svelte"; +import JoinLeaveSection from "./components/settings/JoinLeaveSection.svelte"; +import AntiSpamSection from "./components/settings/AntiSpamSection.svelte"; +import BanFooterSection from "./components/settings/BanFooterSection.svelte"; +import ModmailSection from "./components/settings/ModmailSection.svelte"; + +export interface SectionDef { + id: string; + label: string; + component: Component; +} + +export const sections: SectionDef[] = [ + { id: "mod-channel", label: "Moderator Channel", component: ModChannelSection }, + { id: "infractions", label: "Infractions", component: InfractionsSection }, + { id: "gatekeep", label: "Gatekeep", component: GatekeepSection }, + { id: "join-leave", label: "Join/Leave Messages", component: JoinLeaveSection }, + { id: "anti-spam", label: "Anti-Spam", component: AntiSpamSection }, + { id: "ban-footer", label: "Ban Footer", component: BanFooterSection }, + { id: "modmail", label: "Modmail", component: ModmailSection }, +]; diff --git a/web-dashboard/src/lib/stores/guild-data.svelte.ts b/web-dashboard/src/lib/stores/guild-data.svelte.ts new file mode 100644 index 0000000..e6c05ff --- /dev/null +++ b/web-dashboard/src/lib/stores/guild-data.svelte.ts @@ -0,0 +1,61 @@ +import { settingsClient } from "../api/client"; +import type { Channel, Role, TemplatePlaceholder } from "../../gen/heimdallr/v1/guild_settings_pb"; + +let channels = $state([]); +let roles = $state([]); +let loading = $state(false); +let loadedGuildId = ""; +let pending: Promise | null = null; + +let placeholders = $state([]); +let placeholdersLoaded = false; +let placeholdersPending: Promise | null = null; + +async function fetchGuildData(guildId: string) { + loading = true; + try { + const [chRes, roleRes] = await Promise.all([ + settingsClient.listChannels({ guildId }), + settingsClient.listRoles({ guildId }), + ]); + channels = chRes.channels; + roles = roleRes.roles; + loadedGuildId = guildId; + } finally { + loading = false; + pending = null; + } +} + +async function fetchPlaceholders() { + try { + const res = await settingsClient.getTemplatePlaceholders({}); + placeholders = res.placeholders; + placeholdersLoaded = true; + } finally { + placeholdersPending = null; + } +} + +export function guildDataStore() { + return { + get channels() { return channels; }, + get roles() { return roles; }, + get loading() { return loading; }, + get placeholders() { return placeholders; }, + + load(guildId: string): Promise { + if (guildId === loadedGuildId) return Promise.resolve(); + if (pending) return pending; + pending = fetchGuildData(guildId); + return pending; + }, + + loadPlaceholders(): Promise { + if (placeholdersLoaded) return Promise.resolve(); + if (placeholdersPending) return placeholdersPending; + placeholdersPending = fetchPlaceholders(); + return placeholdersPending; + }, + }; +} diff --git a/web-dashboard/src/lib/stores/guilds.svelte.ts b/web-dashboard/src/lib/stores/guilds.svelte.ts new file mode 100644 index 0000000..849597b --- /dev/null +++ b/web-dashboard/src/lib/stores/guilds.svelte.ts @@ -0,0 +1,21 @@ +import type { Guild } from "../../gen/heimdallr/v1/auth_pb"; + +let list = $state([]); +let loading = $state(false); + +export function guildsStore() { + return { + get guilds() { + return list; + }, + set guilds(g: Guild[]) { + list = g; + }, + get loading() { + return loading; + }, + set loading(l: boolean) { + loading = l; + }, + }; +} diff --git a/web-dashboard/src/lib/stores/settings.svelte.ts b/web-dashboard/src/lib/stores/settings.svelte.ts new file mode 100644 index 0000000..910b794 --- /dev/null +++ b/web-dashboard/src/lib/stores/settings.svelte.ts @@ -0,0 +1,168 @@ +import { create, clone, type Message } from "@bufbuild/protobuf"; +import type { GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { settingsClient } from "../api/client"; +import { + type ModChannelSettings, + ModChannelSettingsSchema, + type InfractionSettings, + InfractionSettingsSchema, + type GatekeepSettings, + GatekeepSettingsSchema, + type JoinLeaveSettings, + JoinLeaveSettingsSchema, + type AntiSpamSettings, + AntiSpamSettingsSchema, + type BanFooterSettings, + BanFooterSettingsSchema, + type ModmailSettings, + ModmailSettingsSchema, +} from "../../gen/heimdallr/v1/guild_settings_pb"; + +export interface SectionState { + data: T; + saved: T; + saving: boolean; + loading: boolean; + error: string | null; +} + +function makeDefault(schema: GenMessage): SectionState { + return { + data: create(schema), + saved: create(schema), + saving: false, + loading: false, + error: null, + }; +} + +async function loadSection( + section: SectionState, + schema: GenMessage, + request: () => Promise, +) { + section.loading = true; + section.error = null; + try { + const res = await request(); + section.data = res; + section.saved = clone(schema, res); + } catch (e: any) { + section.error = e.message; + } finally { + section.loading = false; + } +} + +async function saveSection( + section: SectionState, + schema: GenMessage, + request: () => Promise, +) { + section.saving = true; + section.error = null; + try { + const res = await request(); + section.data = res; + section.saved = clone(schema, res); + } catch (e: any) { + section.error = e.message; + } finally { + section.saving = false; + } +} + +let modChannel = $state>(makeDefault(ModChannelSettingsSchema)); +let infractions = $state>(makeDefault(InfractionSettingsSchema)); +let gatekeep = $state>(makeDefault(GatekeepSettingsSchema)); +let joinLeave = $state>(makeDefault(JoinLeaveSettingsSchema)); +let antiSpam = $state>(makeDefault(AntiSpamSettingsSchema)); +let banFooter = $state>(makeDefault(BanFooterSettingsSchema)); +let modmail = $state>(makeDefault(ModmailSettingsSchema)); + +export function settingsStore() { + return { + get modChannel() { return modChannel; }, + get infractions() { return infractions; }, + get gatekeep() { return gatekeep; }, + get joinLeave() { return joinLeave; }, + get antiSpam() { return antiSpam; }, + get banFooter() { return banFooter; }, + get modmail() { return modmail; }, + + async loadAll(guildId: string) { + await Promise.all([ + this.loadModChannel(guildId), + this.loadInfractions(guildId), + this.loadGatekeep(guildId), + this.loadJoinLeave(guildId), + this.loadAntiSpam(guildId), + this.loadBanFooter(guildId), + this.loadModmail(guildId), + ]); + }, + + async loadModChannel(guildId: string) { + await loadSection(modChannel, ModChannelSettingsSchema, + () => settingsClient.getModChannel({ guildId })); + }, + async saveModChannel() { + await saveSection(modChannel, ModChannelSettingsSchema, + () => settingsClient.updateModChannel({ settings: modChannel.data })); + }, + + async loadInfractions(guildId: string) { + await loadSection(infractions, InfractionSettingsSchema, + () => settingsClient.getInfractionSettings({ guildId })); + }, + async saveInfractions() { + await saveSection(infractions, InfractionSettingsSchema, + () => settingsClient.updateInfractionSettings({ settings: infractions.data })); + }, + + async loadGatekeep(guildId: string) { + await loadSection(gatekeep, GatekeepSettingsSchema, + () => settingsClient.getGatekeepSettings({ guildId })); + }, + async saveGatekeep() { + await saveSection(gatekeep, GatekeepSettingsSchema, + () => settingsClient.updateGatekeepSettings({ settings: gatekeep.data })); + }, + + async loadJoinLeave(guildId: string) { + await loadSection(joinLeave, JoinLeaveSettingsSchema, + () => settingsClient.getJoinLeaveSettings({ guildId })); + }, + async saveJoinLeave() { + await saveSection(joinLeave, JoinLeaveSettingsSchema, + () => settingsClient.updateJoinLeaveSettings({ settings: joinLeave.data })); + }, + + async loadAntiSpam(guildId: string) { + await loadSection(antiSpam, AntiSpamSettingsSchema, + () => settingsClient.getAntiSpamSettings({ guildId })); + }, + async saveAntiSpam() { + await saveSection(antiSpam, AntiSpamSettingsSchema, + () => settingsClient.updateAntiSpamSettings({ settings: antiSpam.data })); + }, + + async loadBanFooter(guildId: string) { + await loadSection(banFooter, BanFooterSettingsSchema, + () => settingsClient.getBanFooterSettings({ guildId })); + }, + async saveBanFooter() { + await saveSection(banFooter, BanFooterSettingsSchema, + () => settingsClient.updateBanFooterSettings({ settings: banFooter.data })); + }, + + async loadModmail(guildId: string) { + await loadSection(modmail, ModmailSettingsSchema, + () => settingsClient.getModmailSettings({ guildId })); + }, + async saveModmail() { + await saveSection(modmail, ModmailSettingsSchema, + () => settingsClient.updateModmailSettings({ settings: modmail.data })); + }, + }; +} diff --git a/web-dashboard/src/lib/stores/user.svelte.ts b/web-dashboard/src/lib/stores/user.svelte.ts new file mode 100644 index 0000000..33149bb --- /dev/null +++ b/web-dashboard/src/lib/stores/user.svelte.ts @@ -0,0 +1,17 @@ +import type { User } from "../../gen/heimdallr/v1/auth_pb"; + +let current = $state(null); + +export function userStore() { + return { + get user() { + return current; + }, + set user(u: User | null) { + current = u; + }, + get isLoggedIn() { + return current !== null; + }, + }; +} diff --git a/web-dashboard/src/lib/utils/dirty.ts b/web-dashboard/src/lib/utils/dirty.ts new file mode 100644 index 0000000..2a840bf --- /dev/null +++ b/web-dashboard/src/lib/utils/dirty.ts @@ -0,0 +1,6 @@ +import { equals, type Message } from "@bufbuild/protobuf"; +import type { GenMessage } from "@bufbuild/protobuf/codegenv2"; + +export function isDirty(schema: GenMessage, data: T, saved: T): boolean { + return !equals(schema, data, saved); +} diff --git a/web-dashboard/src/main.ts b/web-dashboard/src/main.ts new file mode 100644 index 0000000..664a057 --- /dev/null +++ b/web-dashboard/src/main.ts @@ -0,0 +1,9 @@ +import { mount } from 'svelte' +import './app.css' +import App from './App.svelte' + +const app = mount(App, { + target: document.getElementById('app')!, +}) + +export default app diff --git a/web-dashboard/svelte.config.js b/web-dashboard/svelte.config.js new file mode 100644 index 0000000..96b3455 --- /dev/null +++ b/web-dashboard/svelte.config.js @@ -0,0 +1,8 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */ +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/web-dashboard/tsconfig.app.json b/web-dashboard/tsconfig.app.json new file mode 100644 index 0000000..31c18cf --- /dev/null +++ b/web-dashboard/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "module": "ESNext", + "types": ["svelte", "vite/client"], + "noEmit": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "moduleDetection": "force" + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/web-dashboard/tsconfig.json b/web-dashboard/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/web-dashboard/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/web-dashboard/tsconfig.node.json b/web-dashboard/tsconfig.node.json new file mode 100644 index 0000000..8a67f62 --- /dev/null +++ b/web-dashboard/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/web-dashboard/vite.config.ts b/web-dashboard/vite.config.ts new file mode 100644 index 0000000..0da2738 --- /dev/null +++ b/web-dashboard/vite.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' +import tailwindcss from '@tailwindcss/vite' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [svelte(), tailwindcss()], + server: { + proxy: { + '/heimdallr.v1.': { + target: 'http://localhost:8484', + changeOrigin: true, + }, + }, + }, +})