Compare commits

..

No commits in common. "main" and "acl-underscores" have entirely different histories.

107 changed files with 1439 additions and 2669 deletions

View file

@ -71,7 +71,7 @@ builds:
nfpms: nfpms:
- -
package_name: ntfy package_name: ntfy
homepage: https://git.zio.sh/astra/ntfy/v2 homepage: https://heckel.io/ntfy
maintainer: Philipp C. Heckel <philipp.heckel@gmail.com> maintainer: Philipp C. Heckel <philipp.heckel@gmail.com>
description: Simple pub-sub notification service description: Simple pub-sub notification service
license: Apache 2.0 license: Apache 2.0
@ -164,14 +164,14 @@ dockers:
- image_templates: - image_templates:
- &arm64v8_image "binwiederhier/ntfy:{{ .Tag }}-arm64v8" - &arm64v8_image "binwiederhier/ntfy:{{ .Tag }}-arm64v8"
use: buildx use: buildx
dockerfile: Dockerfile-arm dockerfile: Dockerfile
goarch: arm64 goarch: arm64
build_flag_templates: build_flag_templates:
- "--platform=linux/arm64/v8" - "--platform=linux/arm64/v8"
- image_templates: - image_templates:
- &armv7_image "binwiederhier/ntfy:{{ .Tag }}-armv7" - &armv7_image "binwiederhier/ntfy:{{ .Tag }}-armv7"
use: buildx use: buildx
dockerfile: Dockerfile-arm dockerfile: Dockerfile
goarch: arm goarch: arm
goarm: 7 goarm: 7
build_flag_templates: build_flag_templates:
@ -179,7 +179,7 @@ dockers:
- image_templates: - image_templates:
- &armv6_image "binwiederhier/ntfy:{{ .Tag }}-armv6" - &armv6_image "binwiederhier/ntfy:{{ .Tag }}-armv6"
use: buildx use: buildx
dockerfile: Dockerfile-arm dockerfile: Dockerfile
goarch: arm goarch: arm
goarm: 6 goarm: 6
build_flag_templates: build_flag_templates:

View file

@ -9,7 +9,6 @@ LABEL org.opencontainers.image.licenses="Apache-2.0, GPL-2.0"
LABEL org.opencontainers.image.title="ntfy" LABEL org.opencontainers.image.title="ntfy"
LABEL org.opencontainers.image.description="Send push notifications to your phone or desktop using PUT/POST" LABEL org.opencontainers.image.description="Send push notifications to your phone or desktop using PUT/POST"
RUN apk add --no-cache tzdata
COPY ntfy /usr/bin COPY ntfy /usr/bin
EXPOSE 80/tcp EXPOSE 80/tcp

View file

@ -1,18 +0,0 @@
FROM alpine
LABEL org.opencontainers.image.authors="philipp.heckel@gmail.com"
LABEL org.opencontainers.image.url="https://ntfy.sh/"
LABEL org.opencontainers.image.documentation="https://docs.ntfy.sh/"
LABEL org.opencontainers.image.source="https://github.com/binwiederhier/ntfy"
LABEL org.opencontainers.image.vendor="Philipp C. Heckel"
LABEL org.opencontainers.image.licenses="Apache-2.0, GPL-2.0"
LABEL org.opencontainers.image.title="ntfy"
LABEL org.opencontainers.image.description="Send push notifications to your phone or desktop using PUT/POST"
# Alpine does not support adding "tzdata" on ARM anymore, see
# https://github.com/binwiederhier/ntfy/issues/894
COPY ntfy /usr/bin
EXPOSE 80/tcp
ENTRYPOINT ["ntfy"]

View file

@ -2,17 +2,13 @@ FROM golang:1.20-bullseye as builder
ARG VERSION=dev ARG VERSION=dev
ARG COMMIT=unknown ARG COMMIT=unknown
ARG NODE_MAJOR=18
RUN apt-get update && apt-get install -y \ RUN apt-get update
build-essential ca-certificates curl gnupg \ RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash
&& mkdir -p /etc/apt/keyrings \ RUN apt-get install -y \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ build-essential \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" >> /etc/apt/sources.list.d/nodesource.list \ nodejs \
&& apt-get update \ python3-pip
&& apt-get install -y \
python3-pip nodejs \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app WORKDIR /app
ADD Makefile . ADD Makefile .

View file

@ -39,8 +39,8 @@ help:
@echo " make web-deps - Install web app dependencies (npm install the universe)" @echo " make web-deps - Install web app dependencies (npm install the universe)"
@echo " make web-build - Actually build the web app" @echo " make web-build - Actually build the web app"
@echo " make web-lint - Run eslint on the web app" @echo " make web-lint - Run eslint on the web app"
@echo " make web-fmt - Run prettier on the web app" @echo " make web-format - Run prettier on the web app"
@echo " make web-fmt-check - Run prettier on the web app, but don't change anything" @echo " make web-format-check - Run prettier on the web app, but don't change anything"
@echo @echo
@echo "Build documentation:" @echo "Build documentation:"
@echo " make docs - Build the documentation" @echo " make docs - Build the documentation"
@ -111,7 +111,18 @@ build-deps-ubuntu:
docs: docs-deps docs-build docs: docs-deps docs-build
docs-build: .PHONY docs-build: .PHONY
mkdocs build @if ! /bin/echo -e "import sys\nif sys.version_info < (3,8):\n exit(1)" | python3; then \
if which python3.8; then \
echo "python3.8 $(shell which mkdocs) build"; \
python3.8 $(shell which mkdocs) build; \
else \
echo "ERROR: Python version too low. mkdocs-material needs >= 3.8"; \
exit 1; \
fi; \
else \
echo "mkdocs build"; \
mkdocs build; \
fi
docs-deps: .PHONY docs-deps: .PHONY
pip3 install -r requirements.txt pip3 install -r requirements.txt
@ -140,10 +151,10 @@ web-deps:
web-deps-update: web-deps-update:
cd web && npm update cd web && npm update
web-fmt: web-format:
cd web && npm run format cd web && npm run format
web-fmt-check: web-format-check:
cd web && npm run format:check cd web && npm run format:check
web-lint: web-lint:
@ -237,7 +248,7 @@ cli-build-results:
# Test/check targets # Test/check targets
check: test web-fmt-check fmt-check vet web-lint lint staticcheck check: test web-format-check fmt-check vet web-lint lint staticcheck
test: .PHONY test: .PHONY
go test $(shell go list ./... | grep -vE 'ntfy/(test|examples|tools)') go test $(shell go list ./... | grep -vE 'ntfy/(test|examples|tools)')
@ -264,7 +275,7 @@ coverage-upload:
# Lint/formatting targets # Lint/formatting targets
fmt: web-fmt fmt:
gofmt -s -w . gofmt -s -w .
fmt-check: fmt-check:

179
README.md
View file

@ -1,9 +1,186 @@
![ntfy](web/public/static/images/ntfy.png)
# ntfy.sh | Send push notifications to your phone or desktop via PUT/POST # ntfy.sh | Send push notifications to your phone or desktop via PUT/POST
[![Release](https://img.shields.io/github/release/binwiederhier/ntfy.svg?color=success&style=flat-square)](https://github.com/binwiederhier/ntfy/releases/latest)
[![Go Reference](https://pkg.go.dev/badge/heckel.io/ntfy.svg)](https://pkg.go.dev/heckel.io/ntfy)
[![Tests](https://github.com/binwiederhier/ntfy/workflows/test/badge.svg)](https://github.com/binwiederhier/ntfy/actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/binwiederhier/ntfy)](https://goreportcard.com/report/github.com/binwiederhier/ntfy)
[![codecov](https://codecov.io/gh/binwiederhier/ntfy/branch/main/graph/badge.svg?token=A597KQ463G)](https://codecov.io/gh/binwiederhier/ntfy)
[![Discord](https://img.shields.io/discord/874398661709295626?label=Discord)](https://discord.gg/cT7ECsZj9w)
[![Matrix](https://img.shields.io/matrix/ntfy:matrix.org?label=Matrix)](https://matrix.to/#/#ntfy:matrix.org)
[![Matrix space](https://img.shields.io/matrix/ntfy-space:matrix.org?label=Matrix+space)](https://matrix.to/#/#ntfy-space:matrix.org)
[![Lemmy](https://img.shields.io/badge/Lemmy-discuss-green)](https://discuss.ntfy.sh/c/ntfy)
[![Healthcheck](https://healthchecks.io/badge/68b65976-b3b0-4102-aec9-980921/kcoEgrLY.svg)](https://ntfy.statuspage.io/)
[![Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/binwiederhier/ntfy)
**ntfy** (pronounced "*notify*") is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) **ntfy** (pronounced "*notify*") is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)
notification service. With ntfy, you can **send notifications to your phone or desktop via scripts** from any computer, notification service. With ntfy, you can **send notifications to your phone or desktop via scripts** from any computer,
**without having to sign up or pay any fees**. If you'd like to run your own instance of the service, you can easily do **without having to sign up or pay any fees**. If you'd like to run your own instance of the service, you can easily do
so since ntfy is open source. so since ntfy is open source.
You can access the free version of ntfy at **[ntfy.sh](https://ntfy.sh)**. There is also an [open source Android app](https://github.com/binwiederhier/ntfy-android)
available on [Google Play](https://play.google.com/store/apps/details?id=io.heckel.ntfy) or [F-Droid](https://f-droid.org/en/packages/io.heckel.ntfy/),
as well as an [open source iOS app](https://github.com/binwiederhier/ntfy-ios) available on the [App Store](https://apps.apple.com/us/app/ntfy/id1625396347).
### This is a fork of [github.com/binwiederhier/ntfy](https://github.com/binwiederhier/ntfy) <p>
<img src=".github/images/screenshot-curl.png" height="180">
<img src=".github/images/screenshot-web-detail.png" height="180">
<img src=".github/images/screenshot-phone-main.jpg" height="180">
<img src=".github/images/screenshot-phone-detail.jpg" height="180">
<img src=".github/images/screenshot-phone-notification.jpg" height="180">
</p>
## [ntfy Pro](https://ntfy.sh/app) 💸 🎉
I now offer paid plans for [ntfy.sh](https://ntfy.sh/) if you don't want to self-host, or you want to support the development of ntfy (→ [Purchase via web app](https://ntfy.sh/app)). You can **buy a plan for as low as $3.33/month** (if you use promo code `MYTOPIC`, limited time only). You can also donate via [GitHub Sponsors](https://github.com/sponsors/binwiederhier), and [Liberapay](https://liberapay.com/ntfy). I would be very humbled by your sponsorship. ❤️
## **[Documentation](https://ntfy.sh/docs/)**
[Getting started](https://ntfy.sh/docs/) |
[Android/iOS](https://ntfy.sh/docs/subscribe/phone/) |
[API](https://ntfy.sh/docs/publish/) |
[Install / Self-hosting](https://ntfy.sh/docs/install/) |
[Building](https://ntfy.sh/docs/develop/)
## Chat / forum
There are a few ways to get in touch with me and/or the rest of the community. Feel free to use any of these methods. Whatever
works best for you:
* [Discord server](https://discord.gg/cT7ECsZj9w) - direct chat with the community
* [Matrix room #ntfy](https://matrix.to/#/#ntfy:matrix.org) (+ [Matrix space](https://matrix.to/#/#ntfy-space:matrix.org)) - same chat, bridged from Discord
* [Lemmy discussion board](https://discuss.ntfy.sh/c/ntfy) - asynchronous forum (_new as of June 2023_)
* [GitHub issues](https://github.com/binwiederhier/ntfy/issues) - questions, features, bugs
## Announcements / beta testers
For announcements of new releases and cutting-edge beta versions, please subscribe to the [ntfy.sh/announcements](https://ntfy.sh/announcements)
topic. If you'd like to test the iOS app, join [TestFlight](https://testflight.apple.com/join/P1fFnAm9). For Android betas,
join Discord/Matrix (I'll eventually make a testing channel in Google Play).
## Contributing
I welcome any and all contributions. Just create a PR or an issue. For larger features/ideas, please reach out
on Discord/Matrix first to see if I'd accept them. To contribute code, check out the [build instructions](https://ntfy.sh/docs/develop/)
for the server and the Android app. Or, if you'd like to help translate 🇩🇪 🇺🇸 🇧🇬, you can start immediately in
[Hosted Weblate](https://hosted.weblate.org/projects/ntfy/).
<a href="https://hosted.weblate.org/engage/ntfy/">
<img src="https://hosted.weblate.org/widgets/ntfy/-/multi-blue.svg" alt="Translation status" />
</a>
## Sponsors
I have just very recently started accepting donations via [GitHub Sponsors](https://github.com/sponsors/binwiederhier),
and [Liberapay](https://liberapay.com/ntfy). I would be humbled if you helped me carry the server and developer
account costs. Even small donations are very much appreciated. A big fat **Thank You** to the folks already sponsoring ntfy:
<a href="https://github.com/neutralinsomniac"><img src="https://github.com/neutralinsomniac.png" width="40px" /></a>
<a href="https://github.com/aspyct"><img src="https://github.com/aspyct.png" width="40px" /></a>
<a href="https://github.com/nickexyz"><img src="https://github.com/nickexyz.png" width="40px" /></a>
<a href="https://github.com/qcasey"><img src="https://github.com/qcasey.png" width="40px" /></a>
<a href="https://github.com/mckay115"><img src="https://github.com/mckay115.png" width="40px" /></a>
<a href="https://github.com/Salamafet"><img src="https://github.com/Salamafet.png" width="40px" /></a>
<a href="https://github.com/codinghipster"><img src="https://github.com/codinghipster.png" width="40px" /></a>
<a href="https://github.com/HinFort"><img src="https://github.com/HinFort.png" width="40px" /></a>
<a href="https://github.com/Lexevolution"><img src="https://github.com/Lexevolution.png" width="40px" /></a>
<a href="https://github.com/johnnyip"><img src="https://github.com/johnnyip.png" width="40px" /></a>
<a href="https://github.com/JonDerThan"><img src="https://github.com/JonDerThan.png" width="40px" /></a>
<a href="https://github.com/12nick12"><img src="https://github.com/12nick12.png" width="40px" /></a>
<a href="https://github.com/eanplatter"><img src="https://github.com/eanplatter.png" width="40px" /></a>
<a href="https://github.com/fnoelscher"><img src="https://github.com/fnoelscher.png" width="40px" /></a>
<a href="https://github.com/bnorick"><img src="https://github.com/bnorick.png" width="40px" /></a>
<a href="https://github.com/snh"><img src="https://github.com/snh.png" width="40px" /></a>
<a href="https://github.com/hen-x"><img src="https://github.com/hen-x.png" width="40px" /></a>
<a href="https://github.com/JamieGoodson"><img src="https://github.com/JamieGoodson.png" width="40px" /></a>
<a href="https://github.com/cremesk"><img src="https://github.com/cremesk.png" width="40px" /></a>
<a href="https://github.com/dangowans"><img src="https://github.com/dangowans.png" width="40px" /></a>
<a href="https://github.com/mnault"><img src="https://github.com/mnault.png" width="40px" /></a>
<a href="https://github.com/nwithan8"><img src="https://github.com/nwithan8.png" width="40px" /></a>
<a href="https://github.com/peterleiser"><img src="https://github.com/peterleiser.png" width="40px" /></a>
<a href="https://github.com/portothree"><img src="https://github.com/portothree.png" width="40px" /></a>
<a href="https://github.com/finngreig"><img src="https://github.com/finngreig.png" width="40px" /></a>
<a href="https://github.com/skrollme"><img src="https://github.com/skrollme.png" width="40px" /></a>
<a href="https://github.com/gergepalfi"><img src="https://github.com/gergepalfi.png" width="40px" /></a>
<a href="https://github.com/tonyakwei"><img src="https://github.com/tonyakwei.png" width="40px" /></a>
<a href="https://github.com/crosbyh"><img src="https://github.com/crosbyh.png" width="40px" /></a>
<a href="https://github.com/mdlnr"><img src="https://github.com/mdlnr.png" width="40px" /></a>
<a href="https://github.com/p-samuel"><img src="https://github.com/p-samuel.png" width="40px" /></a>
<a href="https://github.com/zugaldia"><img src="https://github.com/zugaldia.png" width="40px" /></a>
<a href="https://github.com/NathanSweet"><img src="https://github.com/NathanSweet.png" width="40px" /></a>
<a href="https://github.com/msdeibel"><img src="https://github.com/msdeibel.png" width="40px" /></a>
<a href="https://github.com/ksurl"><img src="https://github.com/ksurl.png" width="40px" /></a>
<a href="https://github.com/CodingTimeDEV"><img src="https://github.com/CodingTimeDEV.png" width="40px" /></a>
<a href="https://github.com/Terrormixer3000"><img src="https://github.com/Terrormixer3000.png" width="40px" /></a>
<a href="https://github.com/voroskoi"><img src="https://github.com/voroskoi.png" width="40px" /></a>
<a href="https://github.com/Nickwasused"><img src="https://github.com/Nickwasused.png" width="40px" /></a>
<a href="https://github.com/bahur142"><img src="https://github.com/bahur142.png" width="40px" /></a>
<a href="https://github.com/vinhdizzo"><img src="https://github.com/vinhdizzo.png" width="40px" /></a>
<a href="https://github.com/Ge0rg3"><img src="https://github.com/Ge0rg3.png" width="40px" /></a>
<a href="https://github.com/biopsin"><img src="https://github.com/biopsin.png" width="40px" /></a>
<a href="https://github.com/thebino"><img src="https://github.com/thebino.png" width="40px" /></a>
<a href="https://github.com/sky4055"><img src="https://github.com/sky4055.png" width="40px" /></a>
<a href="https://github.com/julianlam"><img src="https://github.com/julianlam.png" width="40px" /></a>
<a href="https://github.com/andreapx"><img src="https://github.com/andreapx.png" width="40px" /></a>
<a href="https://github.com/billycao"><img src="https://github.com/billycao.png" width="40px" /></a>
<a href="https://github.com/zoic21"><img src="https://github.com/zoic21.png" width="40px" /></a>
<a href="https://github.com/IanKulin"><img src="https://github.com/IanKulin.png" width="40px" /></a>
<a href="https://github.com/Joachim256"><img src="https://github.com/Joachim256.png" width="40px" /></a>
<a href="https://github.com/overtone1000"><img src="https://github.com/overtone1000.png" width="40px" /></a>
<a href="https://github.com/oakd"><img src="https://github.com/oakd.png" width="40px" /></a>
<a href="https://github.com/KucharczykL"><img src="https://github.com/KucharczykL.png" width="40px" /></a>
<a href="https://github.com/hansbickhofe"><img src="https://github.com/hansbickhofe.png" width="40px" /></a>
<a href="https://github.com/caseodilla"><img src="https://github.com/caseodilla.png" width="40px" /></a>
<a href="https://github.com/0xAF"><img src="https://github.com/0xAF.png" width="40px" /></a>
<a href="https://github.com/soonoo"><img src="https://github.com/soonoo.png" width="40px" /></a>
<a href="https://github.com/nichu42"><img src="https://github.com/nichu42.png" width="40px" /></a>
<a href="https://github.com/samliebow"><img src="https://github.com/samliebow.png" width="40px" /></a>
<a href="https://github.com/johman10"><img src="https://github.com/johman10.png" width="40px" /></a>
<a href="https://github.com/R-Gld"><img src="https://github.com/R-Gld.png" width="40px" /></a>
<a href="https://github.com/FingerlessGlov3s"><img src="https://github.com/FingerlessGlov3s.png" width="40px" /></a>
<a href="https://github.com/Twisterado"><img src="https://github.com/Twisterado.png" width="40px" /></a>
<a href="https://github.com/ScrumpyJack"><img src="https://github.com/ScrumpyJack.png" width="40px" /></a>
<a href="https://github.com/andrejarrell"><img src="https://github.com/andrejarrell.png" width="40px" /></a>
<a href="https://github.com/oaustegard"><img src="https://github.com/oaustegard.png" width="40px" /></a>
<a href="https://github.com/CreativeWarlock"><img src="https://github.com/CreativeWarlock.png" width="40px" /></a>
<a href="https://github.com/darkdragon-001"><img src="https://github.com/darkdragon-001.png" width="40px" /></a>
<a href="https://github.com/jonathan-kosgei"><img src="https://github.com/jonathan-kosgei.png" width="40px" /></a>
<a href="https://github.com/KevinWang15"><img src="https://github.com/KevinWang15.png" width="40px" /></a>
<a href="https://github.com/darkmattercoder"><img src="https://github.com/darkmattercoder.png" width="40px" /></a>
<a href="https://github.com/bmcgonag"><img src="https://github.com/bmcgonag.png" width="40px" /></a>
<a href="https://github.com/skorokithakis"><img src="https://github.com/skorokithakis.png" width="40px" /></a>
<a href="https://github.com/eenturk"><img src="https://github.com/eenturk.png" width="40px" /></a>
<a href="https://github.com/spirossi"><img src="https://github.com/spirossi.png" width="40px" /></a>
I'd also like to thank JetBrains for their awesome [IntelliJ IDEA](https://www.jetbrains.com/idea/),
and [DigitalOcean](https://m.do.co/c/442b929528db) (*referral link*) for supporting the project:
<a href="https://m.do.co/c/442b929528db"><img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px"></a>
## Code of Conduct
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
**We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.**
_Please be sure to read the complete [Code of Conduct](CODE_OF_CONDUCT.md)._
## License
Made with ❤️ by [Philipp C. Heckel](https://heckel.io).
The project is dual licensed under the [Apache License 2.0](LICENSE) and the [GPLv2 License](LICENSE.GPLv2).
Third party libraries and resources:
* [github.com/urfave/cli](https://github.com/urfave/cli) (MIT) is used to drive the CLI
* [Mixkit sounds](https://mixkit.co/free-sound-effects/notification/) (Mixkit Free License) are used as notification sounds
* [Sounds from notificationsounds.com](https://notificationsounds.com) (Creative Commons Attribution) are used as notification sounds
* [Roboto Font](https://fonts.google.com/specimen/Roboto) (Apache 2.0) is used as a font in everything web
* [React](https://reactjs.org/) (MIT) is used for the web app
* [Material UI components](https://mui.com/) (MIT) are used in the web app
* [MUI dashboard template](https://github.com/mui/material-ui/tree/master/docs/data/material/getting-started/templates/dashboard) (MIT) was used as a basis for the web app
* [Dexie.js](https://github.com/dexie/Dexie.js) (Apache 2.0) is used for web app persistence in IndexedDB
* [GoReleaser](https://goreleaser.com/) (MIT) is used to create releases
* [go-smtp](https://github.com/emersion/go-smtp) (MIT) is used to receive e-mails
* [stretchr/testify](https://github.com/stretchr/testify) (MIT) is used for unit and integration tests
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) (MIT) is used to provide the persistent message cache
* [Firebase Admin SDK](https://github.com/firebase/firebase-admin-go) (Apache 2.0) is used to send FCM messages
* [github/gemoji](https://github.com/github/gemoji) (MIT) is used for emoji support (specifically the [emoji.json](https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json) file)
* [Lightbox with vanilla JS](https://yossiabramov.com/blog/vanilla-js-lightbox) as a lightbox on the landing page
* [HTTP middleware for gzip compression](https://gist.github.com/CJEnright/bc2d8b8dc0c1389a9feeddb110f822d7) (MIT) is used for serving static files
* [Regex for auto-linking](https://github.com/bryanwoods/autolink-js) (MIT) is used to highlight links (the library is not used)
* [Statically linking go-sqlite3](https://www.arp242.net/static-go.html)
* [Linked tabs in mkdocs](https://facelessuser.github.io/pymdown-extensions/extensions/tabbed/#linked-tabs)
* [webpush-go](https://github.com/SherClockHolmes/webpush-go) (MIT) is used to send web push notifications

View file

@ -7,8 +7,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"regexp" "regexp"

View file

@ -2,10 +2,10 @@ package client_test
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/client"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/client"
"heckel.io/ntfy/log"
"heckel.io/ntfy/test"
"os" "os"
"testing" "testing"
"time" "time"

View file

@ -1,8 +1,8 @@
package client_test package client_test
import ( import (
"git.zio.sh/astra/ntfy/v2/client"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/client"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"

View file

@ -2,7 +2,7 @@ package client
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"net/http" "net/http"
"strings" "strings"
"time" "time"

View file

@ -5,9 +5,9 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
) )
func init() { func init() {

View file

@ -2,10 +2,10 @@ package cmd
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/server"
"git.zio.sh/astra/ntfy/v2/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/server"
"heckel.io/ntfy/test"
"testing" "testing"
) )

View file

@ -3,9 +3,9 @@ package cmd
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc" "github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/log"
"os" "os"
"regexp" "regexp"
) )

View file

@ -3,9 +3,9 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"git.zio.sh/astra/ntfy/v2/client"
"git.zio.sh/astra/ntfy/v2/log"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/client"
"heckel.io/ntfy/log"
"os" "os"
"strings" "strings"
"testing" "testing"

View file

@ -2,10 +2,10 @@ package cmd
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc" "github.com/urfave/cli/v2/altsrc"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"heckel.io/ntfy/util"
"os" "os"
) )

View file

@ -3,10 +3,10 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/client"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/client"
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
"io" "io"
"os" "os"
"os/exec" "os/exec"

View file

@ -2,9 +2,9 @@ package cmd
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/test"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/test"
"heckel.io/ntfy/util"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"

View file

@ -5,8 +5,8 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"heckel.io/ntfy/user"
"io/fs" "io/fs"
"math" "math"
"net" "net"
@ -17,12 +17,12 @@ import (
"syscall" "syscall"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/server"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc" "github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/server"
"heckel.io/ntfy/util"
) )
func init() { func init() {

View file

@ -9,12 +9,12 @@ import (
"testing" "testing"
"time" "time"
"git.zio.sh/astra/ntfy/v2/client"
"git.zio.sh/astra/ntfy/v2/test"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/client"
"heckel.io/ntfy/test"
"heckel.io/ntfy/util"
) )
func init() { func init() {

View file

@ -3,10 +3,10 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/client"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/client"
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
"os" "os"
"os/exec" "os/exec"
"os/user" "os/user"

View file

@ -5,9 +5,9 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
) )
func init() { func init() {

View file

@ -1,10 +1,10 @@
package cmd package cmd
import ( import (
"git.zio.sh/astra/ntfy/v2/server"
"git.zio.sh/astra/ntfy/v2/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/server"
"heckel.io/ntfy/test"
"testing" "testing"
) )

View file

@ -5,9 +5,9 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"net/netip" "net/netip"
"time" "time"
) )

View file

@ -2,10 +2,10 @@ package cmd
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/server"
"git.zio.sh/astra/ntfy/v2/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/server"
"heckel.io/ntfy/test"
"regexp" "regexp"
"testing" "testing"
) )

View file

@ -6,13 +6,13 @@ import (
"crypto/subtle" "crypto/subtle"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"os" "os"
"strings" "strings"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc" "github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/util"
) )
const ( const (

View file

@ -1,11 +1,11 @@
package cmd package cmd
import ( import (
"git.zio.sh/astra/ntfy/v2/server"
"git.zio.sh/astra/ntfy/v2/test"
"git.zio.sh/astra/ntfy/v2/user"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/server"
"heckel.io/ntfy/test"
"heckel.io/ntfy/user"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"

View file

@ -3,9 +3,9 @@ package cmd
import ( import (
"testing" "testing"
"git.zio.sh/astra/ntfy/v2/server"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/server"
) )
func TestCLI_WebPush_GenerateKeys(t *testing.T) { func TestCLI_WebPush_GenerateKeys(t *testing.T) {

View file

@ -466,31 +466,6 @@ $ dig A mx1.ntfy.sh +short
3.139.215.220 3.139.215.220
``` ```
### Local-only email
If you want to send emails from an internal service on the same network as your ntfy instance, you do not need to
worry about DNS records at all. Define a port for the SMTP server and pick an SMTP server domain (can be
anything).
=== "/etc/ntfy/server.yml"
``` yaml
smtp-server-listen: ":25"
smtp-server-domain: "example.com"
smtp-server-addr-prefix: "ntfy-" # optional
```
Then, in the email settings of your internal service, set the SMTP server address to the IP address of your
ntfy instance. Set the port to the value you defined in `smtp-server-listen`. Leave any username and password
fields empty. In the "From" address, pick anything (e.g., "alerts@ntfy.sh"); the value doesn't matter.
In the "To" address, put in an email address that follows this pattern: `[topic]@[smtp-server-domain]` (or
`[smtp-server-addr-prefix][topic]@[smtp-server-domain]` if you set `smtp-server-addr-prefix`).
So if you used `example.com` as the SMTP server domain, and you want to send a message to the `email-alerts`
topic, set the "To" address to `email-alerts@example.com`. If the topic has access restrictions, you will need
to include an access token in the "To" address, such as `email-alerts+tk_AbC123dEf456@example.com`.
If the internal service lets you use define an email "Subject", it will become the title of the notification.
The body of the email will become the message of the notification.
## Behind a proxy (TLS, etc.) ## Behind a proxy (TLS, etc.)
!!! warning !!! warning
If you are running ntfy behind a proxy, you must set the `behind-proxy` flag. Otherwise, all visitors are If you are running ntfy behind a proxy, you must set the `behind-proxy` flag. Otherwise, all visitors are
@ -1180,10 +1155,10 @@ and [here](https://easyengine.io/tutorials/nginx/block-wp-login-php-bruteforce-a
## Health checks ## Health checks
A preliminary health check API endpoint is exposed at `/v1/health`. The endpoint returns a `json` response in the format shown below. A preliminary health check API endpoint is exposed at `/v1/health`. The endpoint returns a `json` response in the format shown below.
If a non-200 HTTP status code is returned or if the returned `healthy` field is `false` the ntfy service should be considered as unhealthy. If a non-200 HTTP status code is returned or if the returned `health` field is `false` the ntfy service should be considered as unhealthy.
```json ```json
{"healthy":true} {"health":true}
``` ```
See [Installation for Docker](install.md#docker) for an example of how this could be used in a `docker-compose` environment. See [Installation for Docker](install.md#docker) for an example of how this could be used in a `docker-compose` environment.

View file

@ -429,7 +429,7 @@ steps:
### XCode setup ### XCode setup
1. Follow step 4 of [Add Firebase to your Apple project](https://firebase.google.com/docs/ios/setup) to install the 1. Follow step 4 of [https://firebase.google.com/docs/ios/setup](Add Firebase to your Apple project) to install the
`firebase-ios-sdk` in XCode, if it's not already present - you can select any packages in addition to Firebase Core / Firebase Messaging `firebase-ios-sdk` in XCode, if it's not already present - you can select any packages in addition to Firebase Core / Firebase Messaging
1. Similarly, install the SQLite.swift package dependency in XCode 1. Similarly, install the SQLite.swift package dependency in XCode
1. When running the debug build, ensure XCode is pointed to the connected iOS device - registering for push notifications does not work in the iOS simulators 1. When running the debug build, ensure XCode is pointed to the connected iOS device - registering for push notifications does not work in the iOS simulators

View file

@ -2,9 +2,9 @@
<!-- This file was generated by scripts/emoji-convert.sh --> <!-- This file was generated by scripts/emoji-convert.sh -->
You can [tag messages](publish.md#tags-emojis) with emojis 🥳 🎉 and other relevant strings. Matching tags are automatically You can [tag messages](../publish/#tags-emojis) with emojis 🥳 🎉 and other relevant strings. Matching tags are automatically
converted to emojis. This is a reference of all supported emojis. To learn more about the feature, please refer to the converted to emojis. This is a reference of all supported emojis. To learn more about the feature, please refer to the
[tagging and emojis page](publish.md#tags-emojis). [tagging and emojis page](../publish/#tags-emojis).
<table class="remove-md-box emoji-table"><tr> <table class="remove-md-box emoji-table"><tr>

View file

@ -135,21 +135,6 @@ You can send a message during a workflow run with curl. Here is an example sendi
${{ secrets.NTFY_URL }} ${{ secrets.NTFY_URL }}
``` ```
## Changedetection.io
ntfy is an excellent choice for getting notifications when a website has a change sent to your mobile (or desktop),
[changedetection.io](https://changedetection.io) or on GitHub ([dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io))
uses [apprise](https://github.com/caronc/apprise) library for notification integrations.
To add any ntfy(s) notification to a website change simply add the [ntfy style URL](https://github.com/caronc/apprise/wiki/Notify_ntfy)
to the notification list.
For example `ntfy://{topic}` or `ntfy://{user}:{password}@{host}:{port}/{topics}`
In your changedetection.io installation, click `Edit` > `Notifications` on a single website watch (or group) then add
the special ntfy Apprise Notification URL to the Notification List.
![ntfy alerts on website change](static/img/cdio-setup.jpg)
## Watchtower (shoutrrr) ## Watchtower (shoutrrr)
You can use [shoutrrr](https://containrrr.dev/shoutrrr/latest/services/ntfy/) to send You can use [shoutrrr](https://containrrr.dev/shoutrrr/latest/services/ntfy/) to send
[Watchtower](https://github.com/containrrr/watchtower/) notifications to your ntfy topic. [Watchtower](https://github.com/containrrr/watchtower/) notifications to your ntfy topic.

View file

@ -76,18 +76,6 @@ However, if you still want to disable it, you can do so with the `web-root: disa
Think of the ntfy web app like an Android/iOS app. It is freely available and accessible to anyone, yet useless without Think of the ntfy web app like an Android/iOS app. It is freely available and accessible to anyone, yet useless without
a proper backend. So as long as you secure your backend with ACLs, exposing the ntfy web app to the Internet is harmless. a proper backend. So as long as you secure your backend with ACLs, exposing the ntfy web app to the Internet is harmless.
## If topic names are public, could I not just brute force them?
If you don't have [ACLs set up](config.md#access-control), the topic name is your password, it says so everywhere. If you
choose a easy-to-guess/dumb topic name, people will be able to guess it. If you choose a randomly generated topic name,
the topic is as good as a good password.
As for brute forcing: It's not possible to brute force a ntfy server for very long, as you'll get quickly rate limited.
In the default configuration, you'll be able to do 60 requests as a burst, and then 1 request per 10 seconds. Assuming you
choose a random 10 digit topic name using only A-Z, a-z, 0-9, _ and -, there are 64^10 possible topic names. Even if you
could do hundreds of requests per seconds (which you cannot), it would take many years to brute force a topic name.
For ntfy.sh, there's even a fail2ban in place which will ban your IP pretty quickly.
## Where can I donate? ## Where can I donate?
I have just very recently started accepting donations via [GitHub Sponsors](https://github.com/sponsors/binwiederhier). I have just very recently started accepting donations via [GitHub Sponsors](https://github.com/sponsors/binwiederhier).
I would be humbled if you helped me carry the server and developer account costs. Even small donations are very much I would be humbled if you helped me carry the server and developer account costs. Even small donations are very much

View file

@ -14,15 +14,14 @@ We support amd64, armv7 and arm64.
1. Install ntfy using one of the methods described below 1. Install ntfy using one of the methods described below
2. Then (optionally) edit `/etc/ntfy/server.yml` for the server (Linux only, see [configuration](config.md) or [sample server.yml](https://github.com/binwiederhier/ntfy/blob/main/server/server.yml)) 2. Then (optionally) edit `/etc/ntfy/server.yml` for the server (Linux only, see [configuration](config.md) or [sample server.yml](https://github.com/binwiederhier/ntfy/blob/main/server/server.yml))
3. Or (optionally) create/edit `~/.config/ntfy/client.yml` (for the non-root user), `~/Library/Application Support/ntfy/client.yml` (for the macOS non-root user), or `/etc/ntfy/client.yml` (for the root user), see [sample client.yml](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml)) 3. Or (optionally) create/edit `~/.config/ntfy/client.yml` (for the non-root user) or `/etc/ntfy/client.yml` (for the root user), see [sample client.yml](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml))
To run the ntfy server, then just run `ntfy serve` (or `systemctl start ntfy` when using the deb/rpm). To run the ntfy server, then just run `ntfy serve` (or `systemctl start ntfy` when using the deb/rpm).
To send messages, use `ntfy publish`. To subscribe to topics, use `ntfy subscribe` (see [subscribing via CLI](subscribe/cli.md) To send messages, use `ntfy publish`. To subscribe to topics, use `ntfy subscribe` (see [subscribing via CLI](subscribe/cli.md)
for details). for details).
If you like tutorials, check out :simple-youtube: [Kris Occhipinti's ntfy install guide](https://www.youtube.com/watch?v=bZzqrX05mNU) on YouTube, or If you like video tutorials, check out :simple-youtube: [Kris Occhipinti's ntfy install guide](https://www.youtube.com/watch?v=bZzqrX05mNU).
[Alex's Docker-based setup guide](https://blog.alexsguardian.net/posts/2023/09/12/selfhosting-ntfy/). Both are great It's short and to the point. _I am not affiliated with Kris, I just liked the video._
resources to get started. _I am not affiliated with Kris or Alex, I just liked their video/post._
## Linux binaries ## Linux binaries
Please check out the [releases page](https://github.com/binwiederhier/ntfy/releases) for binaries and Please check out the [releases page](https://github.com/binwiederhier/ntfy/releases) for binaries and

View file

@ -23,8 +23,6 @@ I've added a ⭐ to projects or posts that have a significant following, or had
- [Platypush](https://docs.platypush.tech/platypush/plugins/ntfy.html) - Automation platform aimed to run on any device that can run Python - [Platypush](https://docs.platypush.tech/platypush/plugins/ntfy.html) - Automation platform aimed to run on any device that can run Python
- [diun](https://crazymax.dev/diun/) - Docker Image Update Notifier - [diun](https://crazymax.dev/diun/) - Docker Image Update Notifier
- [Cloudron](https://www.cloudron.io/store/sh.ntfy.cloudronapp.html) - Platform that makes it easy to manage web apps on your server - [Cloudron](https://www.cloudron.io/store/sh.ntfy.cloudronapp.html) - Platform that makes it easy to manage web apps on your server
- [Xitoring](https://xitoring.com/docs/notifications/notification-roles/ntfy/) - Server and Uptime monitoring
- [changedetection.io](https://changedetection.io) ⭐ - Website change detection and notification
## Integration via HTTP/SMTP/etc. ## Integration via HTTP/SMTP/etc.
@ -59,7 +57,6 @@ I've added a ⭐ to projects or posts that have a significant following, or had
- [ntfy_dart](https://github.com/jr1221/ntfy_dart) - Dart wrapper around the ntfy API (Dart) - [ntfy_dart](https://github.com/jr1221/ntfy_dart) - Dart wrapper around the ntfy API (Dart)
- [gotfy](https://github.com/AnthonyHewins/gotfy) - A Go wrapper for the ntfy API (Go) - [gotfy](https://github.com/AnthonyHewins/gotfy) - A Go wrapper for the ntfy API (Go)
- [symfony/ntfy-notifier](https://symfony.com/components/NtfyNotifier) ⭐ - Symfony Notifier integration for ntfy (PHP) - [symfony/ntfy-notifier](https://symfony.com/components/NtfyNotifier) ⭐ - Symfony Notifier integration for ntfy (PHP)
- [ntfy-java](https://github.com/MaheshBabu11/ntfy-java/) - A Java package to interact with a ntfy server (Java)
## CLIs + GUIs ## CLIs + GUIs
@ -130,31 +127,10 @@ I've added a ⭐ to projects or posts that have a significant following, or had
- [msgdrop](https://github.com/jbrubake/msgdrop) - Send and receive encrypted messages (Bash) - [msgdrop](https://github.com/jbrubake/msgdrop) - Send and receive encrypted messages (Bash)
- [vigilant](https://github.com/VerifiedJoseph/vigilant) - Monitor RSS/ATOM and JSON feeds, and send push notifications on new entries (PHP) - [vigilant](https://github.com/VerifiedJoseph/vigilant) - Monitor RSS/ATOM and JSON feeds, and send push notifications on new entries (PHP)
- [ansible-role-ntfy-alertmanager](https://github.com/bleetube/ansible-role-ntfy-alertmanager) - Ansible role to install xenrox/ntfy-alertmanager - [ansible-role-ntfy-alertmanager](https://github.com/bleetube/ansible-role-ntfy-alertmanager) - Ansible role to install xenrox/ntfy-alertmanager
- [NtfyMe-Blender](https://github.com/NotNanook/NtfyMe-Blender) - Blender addon to send notifications to NtfyMe (Python)
- [ntfy-ios-url-share](https://www.icloud.com/shortcuts/be8a7f49530c45f79733cfe3e41887e6) - An iOS shortcut that lets you share URLs easily and quickly.
- [ntfy-ios-filesharing](https://www.icloud.com/shortcuts/fe948d151b2e4ae08fb2f9d6b27d680b) - An iOS shortcut that lets you share files from your share feed to a topic of your choice.
- [systemd-ntfy](https://hackage.haskell.org/package/systemd-ntfy) - monitor a set of systemd services an send a notification to ntfy.sh whenever their status changes
- [RouterOS Scripts](https://git.eworm.de/cgit/routeros-scripts/about/) - a collection of scripts for MikroTik RouterOS
- [ntfy-android-builder](https://github.com/TheBlusky/ntfy-android-builder) - Script for building ntfy-android with custom Firebase configuration (Docker/Shell)
## Blog + forum posts ## Blog + forum posts
- [Installing Self Host NTFY On Linux Using Docker Container](https://www.pinoylinux.org/topicsplus/containers/installing-self-host-ntfy-on-linux-using-docker-container/) - pinoylinux.org - 9/2023 - [How to install and self host an Ntfy server on Linux](https://linuxconfig.org/how-to-install-and-self-host-an-ntfy-server-on-linux) - linuxconfig.org - 9/2021
- [Homelab Notifications with ntfy](https://blog.alexsguardian.net/posts/2023/09/12/selfhosting-ntfy/) ⭐ - alexsguardian.net - 9/2023
- [Why NTFY is the Ultimate Push Notification Tool for Your Needs](https://osintph.medium.com/why-ntfy-is-the-ultimate-push-notification-tool-for-your-needs-e767421c84c5) - osintph.medium.com - 9/2023
- [Supercharge Your Alerts: Ntfy — The Ultimate Push Notification Solution](https://medium.com/spring-boot/supercharge-your-alerts-ntfy-the-ultimate-push-notification-solution-a3dda79651fe) - spring-boot.medium.com - 9/2023
- [Deploy Ntfy using Docker](https://www.linkedin.com/pulse/deploy-ntfy-mohamed-sharfy/) - linkedin.com - 9/2023
- [Send Notifications With Ntfy for New WordPress Posts](https://www.activepieces.com/blog/ntfy-notifications-for-wordpress-new-posts) - activepieces.com - 9/2023
- [Get Ntfy Notifications About New Zendesk Ticket](https://www.activepieces.com/blog/ntfy-notifications-about-new-zendesk-tickets) - activepieces.com - 9/2023
- [Set reminder for recurring events using ntfy & Cron](https://www.youtube.com/watch?v=J3O4aQ-EcYk) - youtube.com - 9/2023
- [ntfy - Installation and full configuration setup](https://www.youtube.com/watch?v=QMy14rGmpFI) - youtube.com - 9/2023
- [How to install Ntfy.sh on Portainer / Docker Compose](https://www.youtube.com/watch?v=utD9GNbAwyg) - youtube.com - 9/2023
- [ntfy - Push-Benachrichtigungen // Push Notifications](https://www.youtube.com/watch?v=LE3vRPPqZOU) - youtube.com - 9/2023
- [Podman Update Notifications via Ntfy](https://rair.dev/podman-upadte-notifications-ntfy/) - rair.dev - 9/2023
- [NetworkChunk - how did I NOT know about this?](https://www.youtube.com/watch?v=poDIT2ruQ9M) ⭐ - youtube.com - 8/2023
- [NTFY - Command-Line Notifications](https://academy.networkchuck.com/blog/ntfy/) - academy.networkchuck.com - 8/2023
- [Open Source Push Notifications! Get notified of any event you can imagine. Triggers abound!](https://www.youtube.com/watch?v=WJgwWXt79pE) ⭐ - youtube.com - 8/2023
- [How to install and self host an Ntfy server on Linux](https://linuxconfig.org/how-to-install-and-self-host-an-ntfy-server-on-linux) - linuxconfig.org - 7/2023
- [Basic website monitoring using cronjobs and ntfy.sh](https://burkhardt.dev/2023/website-monitoring-cron-ntfy/) - burkhardt.dev - 6/2023 - [Basic website monitoring using cronjobs and ntfy.sh](https://burkhardt.dev/2023/website-monitoring-cron-ntfy/) - burkhardt.dev - 6/2023
- [Pingdom alternative in one line of curl through ntfy.sh](https://piqoni.bearblog.dev/uptime-monitoring-in-one-line-of-curl/) - bearblog.dev - 6/2023 - [Pingdom alternative in one line of curl through ntfy.sh](https://piqoni.bearblog.dev/uptime-monitoring-in-one-line-of-curl/) - bearblog.dev - 6/2023
- [#OpenSourceDiscovery 78: ntfy.sh](https://opensourcedisc.substack.com/p/opensourcediscovery-78-ntfysh) - opensourcedisc.substack.com - 6/2023 - [#OpenSourceDiscovery 78: ntfy.sh](https://opensourcedisc.substack.com/p/opensourcediscovery-78-ntfysh) - opensourcedisc.substack.com - 6/2023
@ -238,7 +214,6 @@ ntfy community. Thanks to everyone running a public server. **You guys rock!**
| [ntfy.envs.net](https://ntfy.envs.net) | 🇩🇪 Germany | | [ntfy.envs.net](https://ntfy.envs.net) | 🇩🇪 Germany |
| [ntfy.mzte.de](https://ntfy.mzte.de/) | 🇩🇪 Germany | | [ntfy.mzte.de](https://ntfy.mzte.de/) | 🇩🇪 Germany |
| [ntfy.hostux.net](https://ntfy.hostux.net/) | 🇫🇷 France | | [ntfy.hostux.net](https://ntfy.hostux.net/) | 🇫🇷 France |
| [ntfy.fossman.de](https://ntfy.fossman.de/) | 🇩🇪 Germany |
Please be aware that **server operators can log your messages**. The project also cannot guarantee the reliability Please be aware that **server operators can log your messages**. The project also cannot guarantee the reliability
and uptime of third party servers, so use of each server is **at your own discretion**. and uptime of third party servers, so use of each server is **at your own discretion**.

View file

@ -27,12 +27,11 @@ Be sure that in your selfhosted server:
* Set `upstream-base-url: "https://ntfy.sh"` (**not your own hostname!**) * Set `upstream-base-url: "https://ntfy.sh"` (**not your own hostname!**)
* Ensure that the URL you set in `base-url` **matches exactly** what you set the Default Server in iOS to * Ensure that the URL you set in `base-url` **matches exactly** what you set the Default Server in iOS to
## iOS app seeing "New message", but not real message content ## Firefox on Android not automatically subscribing to web push (see [#789](https://github.com/binwiederhier/ntfy/issues/789))
If you see `New message` notifications on iOS, your iPhone can likely not talk to your self-hosted server. Be sure that ntfy defaults to web-push based subscriptions when installed as a [progressive web app](./subscribe/pwa.md). Firefox
your iOS device and your ntfy server are either on the same network, or that your phone can actually reach the server. Android has an [open bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1796434) where it reports the PWA mode incorrectly.
This causes ntfy to not automatically subscribe to web push, and requires you to go to the ntfy Settings page to enable
Turn on tracing/debugging on the server (via `log-level: trace` or `log-level: debug`, see [troubleshooting](troubleshooting.md)), it manually.
and read docs on [iOS instant notifications](https://docs.ntfy.sh/config/#ios-instant-notifications).
## Safari does not play sounds for web push notifications ## Safari does not play sounds for web push notifications
Safari does not support playing sounds for web push notifications, and treats them all as silent. This will be fixed with Safari does not support playing sounds for web push notifications, and treats them all as silent. This will be fixed with

View file

@ -457,7 +457,6 @@ You can set the priority with the header `X-Priority` (or any of its aliases: `P
=== "PowerShell" === "PowerShell"
``` powershell ``` powershell
$Request = @{ $Request = @{
Method = 'POST'
URI = "https://ntfy.sh/phil_alerts" URI = "https://ntfy.sh/phil_alerts"
Headers = @{ Headers = @{
Priority = "5" Priority = "5"
@ -1034,7 +1033,7 @@ is the only required one:
$Request = @{ $Request = @{
Method = "POST" Method = "POST"
URI = "https://ntfy.sh" URI = "https://ntfy.sh"
Body = ConvertTo-JSON @{ Body = @{
Topic = "mytopic" Topic = "mytopic"
Title = "Low disk space alert" Title = "Low disk space alert"
Message = "Disk space is low at 5.1 GB" Message = "Disk space is low at 5.1 GB"
@ -1043,7 +1042,7 @@ is the only required one:
FileName = "diskspace.jpg" FileName = "diskspace.jpg"
Tags = @("warning", "cd") Tags = @("warning", "cd")
Click = "https://homecamera.lan/xasds1h2xsSsa/" Click = "https://homecamera.lan/xasds1h2xsSsa/"
Actions = @( Actions = ConvertTo-JSON @(
@{ @{
Action = "view" Action = "view"
Label = "Admin panel" Label = "Admin panel"
@ -1131,7 +1130,7 @@ As of today, the following actions are supported:
when the action button is tapped (only supported on Android) when the action button is tapped (only supported on Android)
* [`http`](#send-http-request): Sends HTTP POST/GET/PUT request when the action button is tapped * [`http`](#send-http-request): Sends HTTP POST/GET/PUT request when the action button is tapped
Here's an example of what a notification with actions can look like: Here's an example of what that a notification with actions can look like:
<figure markdown> <figure markdown>
![notification with actions](static/img/android-screenshot-notification-actions.png){ width=500 } ![notification with actions](static/img/android-screenshot-notification-actions.png){ width=500 }
@ -1920,10 +1919,10 @@ And the same example using [JSON publishing](#publish-as-json):
$Request = @{ $Request = @{
Method = "POST" Method = "POST"
URI = "https://ntfy.sh" URI = "https://ntfy.sh"
Body = ConvertTo-Json -Depth 3 @{ Body = @{
Topic = "wifey" Topic = "wifey"
Message = "Your wife requested you send a picture of yourself." Message = "Your wife requested you send a picture of yourself."
Actions = @( Actions = ConvertTo-Json -Depth 3 @(
@{ @{
Action = "broadcast" Action = "broadcast"
Label = "Take picture" Label = "Take picture"
@ -2073,7 +2072,7 @@ Here's an example using the [`X-Actions` header](#using-a-header):
'method' => 'POST', 'method' => 'POST',
'header' => 'header' =>
"Content-Type: text/plain\r\n" . "Content-Type: text/plain\r\n" .
'Actions: http, Close door, https://api.mygarage.lan/, method=PUT, headers.Authorization=Bearer zAzsx1sk.., body={\"action\": \"close\"}', "Actions: http, Close door, https://api.mygarage.lan/, method=PUT, headers.Authorization=Bearer zAzsx1sk.., body={\"action\": \"close\"}",
'content' => 'Garage door has been open for 15 minutes. Close it?' 'content' => 'Garage door has been open for 15 minutes. Close it?'
] ]
])); ]));
@ -2200,10 +2199,10 @@ And the same example using [JSON publishing](#publish-as-json):
$Request = @{ $Request = @{
Method = "POST" Method = "POST"
URI = "https://ntfy.sh" URI = "https://ntfy.sh"
Body = ConvertTo-Json -Depth 3 @{ Body = @{
Topic = "myhome" Topic = "myhome"
Message = "Garage door has been open for 15 minutes. Close it?" Message = "Garage door has been open for 15 minutes. Close it?"
Actions = @( Actions = ConvertTo-Json -Depth 3 @(
@{ @{
Action = "http" Action = "http"
Label = "Close door" Label = "Close door"
@ -2288,7 +2287,7 @@ You can define which URL to open when a notification is clicked. This may be use
to a Zabbix alert or a transaction that you'd like to provide the deep-link for. Tapping the notification will open to a Zabbix alert or a transaction that you'd like to provide the deep-link for. Tapping the notification will open
the web browser (or the app) and open the website. the web browser (or the app) and open the website.
To define a click action for the notification, pass a URL as the value of the `X-Click` header (or its alias `Click`). To define a click action for the notification, pass a URL as the value of the `X-Click` header (or its aliase `Click`).
If you pass a website URL (`http://` or `https://`) the web browser will open. If you pass another URI that can be handled If you pass a website URL (`http://` or `https://`) the web browser will open. If you pass another URI that can be handled
by another app, the responsible app may open. by another app, the responsible app may open.

View file

@ -110,7 +110,7 @@ if you use promo code `MYTOPIC`). ntfy will always remain open source.
## ntfy server v2.4.0 ## ntfy server v2.4.0
Released Apr 26, 2023 Released Apr 26, 2023
This release adds a tiny `v1/stats` endpoint to expose how many messages have been published, and adds support to encode the `X-Title`, This release adds a tiny `v1/stats` endpoint to expose how many messages have been published, and adds suport to encode the `X-Title`,
`X-Message` and `X-Tags` header as RFC 2047. It's a pretty small release, and mainly enables the release of the new ntfy.sh website. `X-Message` and `X-Tags` header as RFC 2047. It's a pretty small release, and mainly enables the release of the new ntfy.sh website.
❤️ If you like ntfy, **please consider sponsoring me** via [GitHub Sponsors](https://github.com/sponsors/binwiederhier) ❤️ If you like ntfy, **please consider sponsoring me** via [GitHub Sponsors](https://github.com/sponsors/binwiederhier)
@ -1273,7 +1273,7 @@ Released Dec 28, 2021
**Features & bug fixes:** **Features & bug fixes:**
* [Publish messages via e-mail](publish.md#e-mail-publishing) #66 * [Publish messages via e-mail](ntfy.sh/docs/publish/#e-mail-publishing) #66
* Server-side work to support [unifiedpush.org](https://unifiedpush.org) #64 * Server-side work to support [unifiedpush.org](https://unifiedpush.org) #64
* Fixing the Santa bug #65 * Fixing the Santa bug #65
@ -1288,10 +1288,6 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
**Bug fixes + maintenance:** **Bug fixes + maintenance:**
* Fix ACL issue with topic patterns containing underscores ([#840](https://github.com/binwiederhier/ntfy/issues/840), thanks to [@Joe-0237](https://github.com/Joe-0237) for reporting) * Fix ACL issue with topic patterns containing underscores ([#840](https://github.com/binwiederhier/ntfy/issues/840), thanks to [@Joe-0237](https://github.com/Joe-0237) for reporting)
* Re-add `tzdata` to Docker images for amd64 image ([#894](https://github.com/binwiederhier/ntfy/issues/894), [#307](https://github.com/binwiederhier/ntfy/pull/307))
* Add special logic to ignore `Priority` header if it resembled a RFC 9218 value ([#851](https://github.com/binwiederhier/ntfy/pull/851)/[#895](https://github.com/binwiederhier/ntfy/pull/895), thanks to [@gusdleon](https://github.com/gusdleon), see also [#351](https://github.com/binwiederhier/ntfy/issues/351), [#353](https://github.com/binwiederhier/ntfy/issues/353), [#461](https://github.com/binwiederhier/ntfy/issues/461))
* PWA: hide install prompt on macOS 14 Safari ([#899](https://github.com/binwiederhier/ntfy/pull/899), thanks to [@nihalgonsalves](https://github.com/nihalgonsalves))
* Fix web app crash in Edge for languages with underline in locale ([#922](https://github.com/binwiederhier/ntfy/pull/922)/[#912](https://github.com/binwiederhier/ntfy/issues/912)/[#852](https://github.com/binwiederhier/ntfy/issues/852), thanks to [@imkero](https://github.com/imkero))
### ntfy Android app v1.16.1 (UNRELEASED) ### ntfy Android app v1.16.1 (UNRELEASED)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

View file

@ -10,7 +10,7 @@ to topics via the ntfy CLI. The CLI is included in the same `ntfy` binary that c
## Install + configure ## Install + configure
To install the ntfy CLI, simply **follow the steps outlined on the [install page](../install.md)**. The ntfy server and To install the ntfy CLI, simply **follow the steps outlined on the [install page](../install.md)**. The ntfy server and
client are the same binary, so it's all very convenient. After installing, you can (optionally) configure the client client are the same binary, so it's all very convenient. After installing, you can (optionally) configure the client
by creating `~/.config/ntfy/client.yml` (for the non-root user), `~/Library/Application Support/ntfy/client.yml` (for the macOS non-root user), or `/etc/ntfy/client.yml` (for the root user). You by creating `~/.config/ntfy/client.yml` (for the non-root user), or `/etc/ntfy/client.yml` (for the root user). You
can find a [skeleton config](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml) on GitHub. can find a [skeleton config](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml) on GitHub.
If you just want to use [ntfy.sh](https://ntfy.sh), you don't have to change anything. If you **self-host your own server**, If you just want to use [ntfy.sh](https://ntfy.sh), you don't have to change anything. If you **self-host your own server**,

View file

@ -26,13 +26,6 @@ app drawer:
<a href="../../static/img/pwa-badge.png"><img src="../../static/img/pwa-badge.png"/></a> <a href="../../static/img/pwa-badge.png"><img src="../../static/img/pwa-badge.png"/></a>
</div> </div>
### Safari on macOS
To install and register the web app via Safari, click on the Share menu and click Add to Dock. You need to be on macOS Sonoma (14) or higher.
<div id="pwa-screenshots-safari-desktop" class="screenshots">
<a href="../../static/img/pwa-install-macos-safari-add-to-dock.png"><img src="../../static/img/pwa-install-macos-safari-add-to-dock.png"/></a>
</div>
### Chrome/Firefox on Android ### Chrome/Firefox on Android
For Chrome on Android, either click the "Add to Home Screen" banner at the bottom of the screen, or select "Install app" For Chrome on Android, either click the "Add to Home Screen" banner at the bottom of the screen, or select "Install app"
in the menu, and then click "Install" in the popup menu. After installation, you can find the app in your app drawer, in the menu, and then click "Install" in the popup menu. After installation, you can find the app in your app drawer,

75
go.mod
View file

@ -1,25 +1,25 @@
module git.zio.sh/astra/ntfy/v2 module heckel.io/ntfy
go 1.18 go 1.18
require ( require (
cloud.google.com/go/firestore v1.14.0 // indirect cloud.google.com/go/firestore v1.12.0 // indirect
cloud.google.com/go/storage v1.34.1 // indirect cloud.google.com/go/storage v1.32.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect github.com/BurntSushi/toml v1.3.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/emersion/go-smtp v0.18.0 github.com/emersion/go-smtp v0.18.0
github.com/gabriel-vasile/mimetype v1.4.3 github.com/gabriel-vasile/mimetype v1.4.2
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.0
github.com/mattn/go-sqlite3 v1.14.18 github.com/mattn/go-sqlite3 v1.14.17
github.com/olebedev/when v1.0.0 github.com/olebedev/when v1.0.0
github.com/stretchr/testify v1.8.1 github.com/stretchr/testify v1.8.1
github.com/urfave/cli/v2 v2.25.7 github.com/urfave/cli/v2 v2.25.7
golang.org/x/crypto v0.14.0 golang.org/x/crypto v0.12.0
golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/oauth2 v0.11.0 // indirect
golang.org/x/sync v0.5.0 golang.org/x/sync v0.3.0
golang.org/x/term v0.13.0 golang.org/x/term v0.11.0
golang.org/x/time v0.4.0 golang.org/x/time v0.3.0
google.golang.org/api v0.149.0 google.golang.org/api v0.138.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
@ -28,18 +28,18 @@ replace github.com/emersion/go-smtp => github.com/emersion/go-smtp v0.17.0 // Pi
require github.com/pkg/errors v0.9.1 // indirect require github.com/pkg/errors v0.9.1 // indirect
require ( require (
firebase.google.com/go/v4 v4.12.1 firebase.google.com/go/v4 v4.12.0
github.com/SherClockHolmes/webpush-go v1.3.0 github.com/SherClockHolmes/webpush-go v1.2.0
github.com/prometheus/client_golang v1.17.0 github.com/prometheus/client_golang v1.16.0
github.com/stripe/stripe-go/v74 v74.30.0 github.com/stripe/stripe-go/v74 v74.30.0
) )
require ( require (
cloud.google.com/go v0.110.10 // indirect cloud.google.com/go v0.110.7 // indirect
cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/iam v1.1.2 // indirect
cloud.google.com/go/longrunning v0.5.4 // indirect cloud.google.com/go/longrunning v0.5.1 // indirect
github.com/AlekSi/pointer v1.2.0 // indirect github.com/AlekSi/pointer v1.2.0 // indirect
github.com/MicahParks/keyfunc v1.9.0 // indirect github.com/MicahParks/keyfunc v1.9.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
@ -50,30 +50,31 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/s2a-go v0.1.7 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.4.0 // indirect github.com/google/s2a-go v0.1.5 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/objx v0.5.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.14.0 // indirect golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.12.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.8 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/appengine/v2 v2.0.5 // indirect google.golang.org/appengine/v2 v2.0.4 // indirect
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/genproto v0.0.0-20230815205213-6bfd019c3878 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230815205213-6bfd019c3878 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 // indirect
google.golang.org/grpc v1.59.0 // indirect google.golang.org/grpc v1.57.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

194
go.sum
View file

@ -1,20 +1,21 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= cloud.google.com/go/firestore v1.12.0 h1:aeEA/N7DW7+l2u5jtkO8I0qv0D95YwjggD8kUHrTHO4=
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= cloud.google.com/go/firestore v1.12.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4=
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
cloud.google.com/go/storage v1.34.1 h1:H2Af2dU5J0PF7A5B+ECFIce+RqxVnrVilO+cu0TS3MI= cloud.google.com/go/storage v1.32.0 h1:5w6DxEGOnktmJHarxAOUywxVW9lbNWIzlzzUltG/3+o=
cloud.google.com/go/storage v1.34.1/go.mod h1:VN1ElqqvR9adg1k9xlkUJ55cMOP1/QjnNNuT5xQL6dY= cloud.google.com/go/storage v1.32.0/go.mod h1:Hhh/dogNRGca7IWv1RC2YqEn0c0G77ctA/OxflYkiD8=
firebase.google.com/go/v4 v4.12.1 h1:tDNvobifGsx/1HSFLnM0fmNfx/CDZSgsTO2KhZtgpcs= firebase.google.com/go/v4 v4.12.0 h1:I6dCkcWUMFNkFdWgzlf8SLWecQnKdFgJhMv5fT9l1qI=
firebase.google.com/go/v4 v4.12.1/go.mod h1:60c36dWLK4+j05Vw5XMllek3b3PCynU3BfI46OSwsUE= firebase.google.com/go/v4 v4.12.0/go.mod h1:60c36dWLK4+j05Vw5XMllek3b3PCynU3BfI46OSwsUE=
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@ -22,17 +23,24 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o= github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
github.com/SherClockHolmes/webpush-go v1.3.0 h1:CAu3FvEE9QS4drc3iKNgpBWFfGqNthKlZhp5QpYnu6k= github.com/SherClockHolmes/webpush-go v1.2.0 h1:sGv0/ZWCvb1HUH+izLqrb2i68HuqD/0Y+AmGQfyqKJA=
github.com/SherClockHolmes/webpush-go v1.3.0/go.mod h1:AxRHmJuYwKGG1PVgYzToik1lphQvDnqFYDqimHvwhIw= github.com/SherClockHolmes/webpush-go v1.2.0/go.mod h1:w6X47YApe/B9wUz2Wh8xukxlyupaxSSEbu6yKJcHN2w=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -45,9 +53,12 @@ github.com/emersion/go-smtp v0.17.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVR
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@ -59,13 +70,16 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -78,41 +92,44 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/olebedev/when v1.0.0 h1:T2DZCj8HxUhOVxcqaLOmzuTr+iZLtMHsZEim7mjIA2w= github.com/olebedev/when v1.0.0 h1:T2DZCj8HxUhOVxcqaLOmzuTr+iZLtMHsZEim7mjIA2w=
github.com/olebedev/when v1.0.0/go.mod h1:T0THb4kP9D3NNqlvCwIG4GyUioTAzEhB4RNVzig/43E= github.com/olebedev/when v1.0.0/go.mod h1:T0THb4kP9D3NNqlvCwIG4GyUioTAzEhB4RNVzig/43E=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -120,6 +137,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -134,72 +152,72 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -207,35 +225,39 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/api v0.138.0 h1:K/tVp05MxNVbHShRw9m7e9VJGdagNeTdMzqPH7AUqr0=
google.golang.org/api v0.138.0/go.mod h1:4xyob8CxC+0GChNBvEUAk8VBKNvYOTWM9T3v3UfRxuY=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine/v2 v2.0.5 h1:4C+F3Cd3L2nWEfSmFEZDPjQvDwL8T0YCeZBysZifP3k= google.golang.org/appengine/v2 v2.0.4 h1:aAAPYixP9EfTJjNO6F46afaxp+jfzb0VgwVjMeLBtF4=
google.golang.org/appengine/v2 v2.0.5/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI= google.golang.org/appengine/v2 v2.0.4/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U= google.golang.org/genproto v0.0.0-20230815205213-6bfd019c3878 h1:Iveh6tGCJkHAjJgEqUQYGDGgbwmhjoAOz8kO/ajxefY=
google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= google.golang.org/genproto v0.0.0-20230815205213-6bfd019c3878/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405 h1:HJMDndgxest5n2y77fnErkM62iUsptE/H8p0dC2Huo4= google.golang.org/genproto/googleapis/api v0.0.0-20230815205213-6bfd019c3878 h1:WGq4lvB/mlicysM/dUT3SBvijH4D3sm/Ny1A4wmt2CI=
google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= google.golang.org/genproto/googleapis/api v0.0.0-20230815205213-6bfd019c3878/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik= google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 h1:lv6/DhyiFFGsmzxbsUUTOkN29II+zeWHxvT8Lpdxsv0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -252,6 +274,8 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -3,7 +3,7 @@ package log
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"log" "log"
"os" "os"
"sort" "sort"

View file

@ -2,8 +2,8 @@ package main
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/cmd"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"heckel.io/ntfy/cmd"
"os" "os"
"runtime" "runtime"
) )

View file

@ -25,9 +25,9 @@ elif [[ "$1" == *.md ]]; then
<!-- This file was generated by scripts/emoji-convert.sh --> <!-- This file was generated by scripts/emoji-convert.sh -->
You can [tag messages](publish.md#tags-emojis) with emojis 🥳 🎉 and other relevant strings. Matching tags are automatically You can [tag messages](../publish/#tags-emojis) with emojis 🥳 🎉 and other relevant strings. Matching tags are automatically
converted to emojis. This is a reference of all supported emojis. To learn more about the feature, please refer to the converted to emojis. This is a reference of all supported emojis. To learn more about the feature, please refer to the
[tagging and emojis page](publish.md#tags-emojis). [tagging and emojis page](../publish/#tags-emojis).
<table class=\"remove-md-box emoji-table\"><tr> <table class=\"remove-md-box emoji-table\"><tr>
" > "$1" " > "$1"

View file

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"regexp" "regexp"
"strings" "strings"
"unicode/utf8" "unicode/utf8"

View file

@ -5,7 +5,7 @@ import (
"net/netip" "net/netip"
"time" "time"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
) )
// Defines default config settings (excluding limits, see below) // Defines default config settings (excluding limits, see below)

View file

@ -1,8 +1,8 @@
package server_test package server_test
import ( import (
"git.zio.sh/astra/ntfy/v2/server"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"heckel.io/ntfy/server"
"testing" "testing"
) )

View file

@ -3,7 +3,7 @@ package server
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"net/http" "net/http"
) )

View file

@ -3,8 +3,8 @@ package server
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"

View file

@ -3,8 +3,8 @@ package server
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/util"
"os" "os"
"strings" "strings"
"testing" "testing"

View file

@ -2,10 +2,10 @@ package server
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/emersion/go-smtp" "github.com/emersion/go-smtp"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
"net/http" "net/http"
"strings" "strings"
"unicode/utf8" "unicode/utf8"

View file

@ -9,9 +9,9 @@ import (
"strings" "strings"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
_ "github.com/mattn/go-sqlite3" // SQLite driver _ "github.com/mattn/go-sqlite3" // SQLite driver
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
) )
var ( var (

View file

@ -26,13 +26,13 @@ import (
"time" "time"
"unicode/utf8" "unicode/utf8"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/emersion/go-smtp" "github.com/emersion/go-smtp"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"heckel.io/ntfy/log"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
) )
// Server is the main server, providing the UI and API for ntfy // Server is the main server, providing the UI and API for ntfy

View file

@ -2,9 +2,9 @@ package server
import ( import (
"encoding/json" "encoding/json"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"net/http" "net/http"
"net/netip" "net/netip"
"strings" "strings"

View file

@ -2,10 +2,10 @@ package server
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/log"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"io" "io"
"net/netip" "net/netip"
"path/filepath" "path/filepath"

View file

@ -1,7 +1,7 @@
package server package server
import ( import (
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"net/http" "net/http"
) )

View file

@ -1,9 +1,9 @@
package server package server
import ( import (
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "time"

View file

@ -7,9 +7,9 @@ import (
firebase "firebase.google.com/go/v4" firebase "firebase.google.com/go/v4"
"firebase.google.com/go/v4/messaging" "firebase.google.com/go/v4/messaging"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"google.golang.org/api/option" "google.golang.org/api/option"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"strings" "strings"
) )

View file

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"net/netip" "net/netip"
"strings" "strings"
"sync" "sync"

View file

@ -1,8 +1,8 @@
package server package server
import ( import (
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"strings" "strings"
) )

View file

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"strings" "strings"

View file

@ -3,7 +3,7 @@ package server
import ( import (
"net/http" "net/http"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
) )
type contextKey int type contextKey int

View file

@ -4,9 +4,6 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
portalsession "github.com/stripe/stripe-go/v74/billingportal/session" portalsession "github.com/stripe/stripe-go/v74/billingportal/session"
"github.com/stripe/stripe-go/v74/checkout/session" "github.com/stripe/stripe-go/v74/checkout/session"
@ -14,6 +11,9 @@ import (
"github.com/stripe/stripe-go/v74/price" "github.com/stripe/stripe-go/v74/price"
"github.com/stripe/stripe-go/v74/subscription" "github.com/stripe/stripe-go/v74/subscription"
"github.com/stripe/stripe-go/v74/webhook" "github.com/stripe/stripe-go/v74/webhook"
"heckel.io/ntfy/log"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"net/netip" "net/netip"

View file

@ -2,12 +2,12 @@ package server
import ( import (
"encoding/json" "encoding/json"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"golang.org/x/time/rate" "golang.org/x/time/rate"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"io" "io"
"net/netip" "net/netip"
"path/filepath" "path/filepath"

View file

@ -6,8 +6,8 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"heckel.io/ntfy/user"
"io" "io"
"math/rand" "math/rand"
"net/http" "net/http"
@ -22,10 +22,10 @@ import (
"testing" "testing"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/SherClockHolmes/webpush-go" "github.com/SherClockHolmes/webpush-go"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -329,27 +329,6 @@ func TestServer_PublishPriority(t *testing.T) {
require.Equal(t, 40007, toHTTPError(t, response.Body.String()).Code) require.Equal(t, 40007, toHTTPError(t, response.Body.String()).Code)
} }
func TestServer_PublishPriority_SpecialHTTPHeader(t *testing.T) {
s := newTestServer(t, newTestConfig(t))
response := request(t, s, "POST", "/mytopic", "test", map[string]string{
"Priority": "u=4",
"X-Priority": "5",
})
require.Equal(t, 5, toMessage(t, response.Body.String()).Priority)
response = request(t, s, "POST", "/mytopic?priority=4", "test", map[string]string{
"Priority": "u=9",
})
require.Equal(t, 4, toMessage(t, response.Body.String()).Priority)
response = request(t, s, "POST", "/mytopic", "test", map[string]string{
"p": "2",
"priority": "u=9, i",
})
require.Equal(t, 2, toMessage(t, response.Body.String()).Priority)
}
func TestServer_PublishGETOnlyOneTopic(t *testing.T) { func TestServer_PublishGETOnlyOneTopic(t *testing.T) {
// This tests a bug that allowed publishing topics with a comma in the name (no ticket) // This tests a bug that allowed publishing topics with a comma in the name (no ticket)
@ -512,8 +491,6 @@ func TestServer_PublishAtAndPrune(t *testing.T) {
messages := toMessages(t, response.Body.String()) messages := toMessages(t, response.Body.String())
require.Equal(t, 1, len(messages)) // Not affected by pruning require.Equal(t, 1, len(messages)) // Not affected by pruning
require.Equal(t, "a message", messages[0].Message) require.Equal(t, "a message", messages[0].Message)
time.Sleep(time.Second) // FIXME CI failing not sure why
} }
func TestServer_PublishAndMultiPoll(t *testing.T) { func TestServer_PublishAndMultiPoll(t *testing.T) {

View file

@ -4,9 +4,9 @@ import (
"bytes" "bytes"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"

View file

@ -1,9 +1,9 @@
package server package server
import ( import (
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"

View file

@ -7,9 +7,9 @@ import (
"regexp" "regexp"
"strings" "strings"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/user"
"github.com/SherClockHolmes/webpush-go" "github.com/SherClockHolmes/webpush-go"
"heckel.io/ntfy/log"
"heckel.io/ntfy/user"
) )
const ( const (

View file

@ -3,9 +3,9 @@ package server
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/user"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/user"
"heckel.io/ntfy/util"
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"

View file

@ -11,8 +11,8 @@ import (
"sync" "sync"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
) )
type mailer interface { type mailer interface {

View file

@ -5,8 +5,8 @@ import (
"sync" "sync"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
) )
const ( const (

View file

@ -5,10 +5,10 @@ import (
"net/netip" "net/netip"
"time" "time"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
) )
// List of possible events // List of possible events

View file

@ -3,19 +3,15 @@ package server
import ( import (
"context" "context"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"io" "io"
"mime" "mime"
"net/http" "net/http"
"net/netip" "net/netip"
"regexp"
"strings" "strings"
) )
var ( var mimeDecoder mime.WordDecoder
mimeDecoder mime.WordDecoder
priorityHeaderIgnoreRegex = regexp.MustCompile(`^u=\d,\s*(i|\d)$|^u=\d$`)
)
func readBoolParam(r *http.Request, defaultValue bool, names ...string) bool { func readBoolParam(r *http.Request, defaultValue bool, names ...string) bool {
value := strings.ToLower(readParam(r, names...)) value := strings.ToLower(readParam(r, names...))
@ -54,9 +50,9 @@ func readParam(r *http.Request, names ...string) string {
func readHeaderParam(r *http.Request, names ...string) string { func readHeaderParam(r *http.Request, names ...string) string {
for _, name := range names { for _, name := range names {
value := strings.TrimSpace(maybeDecodeHeader(name, r.Header.Get(name))) value := maybeDecodeHeader(r.Header.Get(name))
if value != "" { if value != "" {
return value return strings.TrimSpace(value)
} }
} }
return "" return ""
@ -130,26 +126,10 @@ func fromContext[T any](r *http.Request, key contextKey) (T, error) {
return t, nil return t, nil
} }
// maybeDecodeHeader decodes the given header value if it is MIME encoded, e.g. "=?utf-8?q?Hello_World?=", func maybeDecodeHeader(header string) string {
// or returns the original header value if it is not MIME encoded. It also calls maybeIgnoreSpecialHeader decoded, err := mimeDecoder.DecodeHeader(header)
// to ignore new HTTP "Priority" header.
func maybeDecodeHeader(name, value string) string {
decoded, err := mimeDecoder.DecodeHeader(value)
if err != nil { if err != nil {
return maybeIgnoreSpecialHeader(name, value) return header
} }
return maybeIgnoreSpecialHeader(name, decoded) return decoded
}
// maybeIgnoreSpecialHeader ignores new HTTP "Priority" header (see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority)
//
// Cloudflare (and potentially other providers) add this to requests when forwarding to the backend (ntfy),
// so we just ignore it. If the "Priority" header is set to "u=*, i" or "u=*" (by Cloudflare), the header will be ignored.
// Returning an empty string will allow the rest of the logic to continue searching for another header (x-priority, prio, p),
// or in the Query parameters.
func maybeIgnoreSpecialHeader(name, value string) string {
if strings.ToLower(name) == "priority" && priorityHeaderIgnoreRegex.MatchString(strings.TrimSpace(value)) {
return ""
}
return value
} }

View file

@ -2,9 +2,9 @@ package server
import ( import (
"bytes" "bytes"
"crypto/rand"
"fmt" "fmt"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"math/rand"
"net/http" "net/http"
"strings" "strings"
"testing" "testing"
@ -75,16 +75,3 @@ Accept: */*
(peeked bytes not UTF-8, peek limit of 4096 bytes reached, hex: ` + fmt.Sprintf("%x", body[:4096]) + ` ...)` (peeked bytes not UTF-8, peek limit of 4096 bytes reached, hex: ` + fmt.Sprintf("%x", body[:4096]) + ` ...)`
require.Equal(t, expected, renderHTTPRequest(r)) require.Equal(t, expected, renderHTTPRequest(r))
} }
func TestMaybeIgnoreSpecialHeader(t *testing.T) {
require.Empty(t, maybeIgnoreSpecialHeader("priority", "u=1"))
require.Empty(t, maybeIgnoreSpecialHeader("Priority", "u=1"))
require.Empty(t, maybeIgnoreSpecialHeader("Priority", "u=1, i"))
}
func TestMaybeDecodeHeaders(t *testing.T) {
r, _ := http.NewRequest("GET", "http://ntfy.sh/mytopic/json?since=all", nil)
r.Header.Set("Priority", "u=1") // Cloudflare priority header
r.Header.Set("X-Priority", "5") // ntfy priority header
require.Equal(t, "5", readHeaderParam(r, "x-priority", "priority", "p"))
}

View file

@ -2,14 +2,14 @@ package server
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log" "heckel.io/ntfy/log"
"git.zio.sh/astra/ntfy/v2/user" "heckel.io/ntfy/user"
"net/netip" "net/netip"
"sync" "sync"
"time" "time"
"git.zio.sh/astra/ntfy/v2/util"
"golang.org/x/time/rate" "golang.org/x/time/rate"
"heckel.io/ntfy/util"
) )
const ( const (

View file

@ -3,7 +3,7 @@ package server
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"git.zio.sh/astra/ntfy/v2/util" "heckel.io/ntfy/util"
"net/netip" "net/netip"
"time" "time"

View file

@ -2,7 +2,7 @@ package test
import ( import (
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/server" "heckel.io/ntfy/server"
"math/rand" "math/rand"
"net/http" "net/http"
"path/filepath" "path/filepath"

View file

@ -6,11 +6,11 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/log"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/mattn/go-sqlite3" "github.com/mattn/go-sqlite3"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"heckel.io/ntfy/log"
"heckel.io/ntfy/util"
"net/netip" "net/netip"
"strings" "strings"
"sync" "sync"

View file

@ -3,10 +3,10 @@ package user
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"heckel.io/ntfy/util"
"net/netip" "net/netip"
"path/filepath" "path/filepath"
"strings" "strings"

View file

@ -2,8 +2,8 @@ package user
import ( import (
"errors" "errors"
"git.zio.sh/astra/ntfy/v2/log"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"heckel.io/ntfy/log"
"net/netip" "net/netip"
"regexp" "regexp"
"strings" "strings"

View file

@ -1,8 +1,8 @@
package util_test package util_test
import ( import (
"git.zio.sh/astra/ntfy/v2/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"heckel.io/ntfy/util"
"math/rand" "math/rand"
"sync" "sync"
"testing" "testing"

View file

@ -161,6 +161,11 @@ func ParsePriority(priority string) (int, error) {
case "5", "max", "urgent": case "5", "max", "urgent":
return 5, nil return 5, nil
default: default:
// Ignore new HTTP Priority header (see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority)
// Cloudflare adds this to requests when forwarding to the backend (ntfy), so we just ignore it.
if strings.HasPrefix(p, "u=") {
return 3, nil
}
return 0, errInvalidPriority return 0, errInvalidPriority
} }
} }

View file

@ -87,6 +87,15 @@ func TestParsePriority_Invalid(t *testing.T) {
} }
} }
func TestParsePriority_HTTPSpecPriority(t *testing.T) {
priorities := []string{"u=1", "u=3", "u=7, i"} // see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority
for _, priority := range priorities {
actual, err := ParsePriority(priority)
require.Nil(t, err)
require.Equal(t, 3, actual) // Always expect 3!
}
}
func TestPriorityString(t *testing.T) { func TestPriorityString(t *testing.T) {
priorities := []int{0, 1, 2, 3, 4, 5} priorities := []int{0, 1, 2, 3, 4, 5}
expected := []string{"default", "min", "low", "default", "high", "max"} expected := []string{"default", "min", "low", "default", "high", "max"}

View file

@ -22,7 +22,7 @@
<!-- Previews in Google, Slack, WhatsApp, etc. --> <!-- Previews in Google, Slack, WhatsApp, etc. -->
<meta <meta
name="description" name="description"
content="ntfy lets you send push notifications via scripts from any computer or phone. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://git.zio.sh/astra/ntfy/v2." content="ntfy lets you send push notifications via scripts from any computer or phone. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy."
/> />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:locale" content="en_US" /> <meta property="og:locale" content="en_US" />
@ -30,7 +30,7 @@
<meta property="og:title" content="ntfy web" /> <meta property="og:title" content="ntfy web" />
<meta <meta
property="og:description" property="og:description"
content="ntfy lets you send push notifications via scripts from any computer or phone. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://git.zio.sh/astra/ntfy/v2." content="ntfy lets you send push notifications via scripts from any computer or phone. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy."
/> />
<meta property="og:image" content="/static/images/ntfy.png" /> <meta property="og:image" content="/static/images/ntfy.png" />
<meta property="og:url" content="https://ntfy.sh" /> <meta property="og:url" content="https://ntfy.sh" />

1530
web/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -152,7 +152,7 @@
"publish_dialog_chip_delay_label": "تأخير التسليم", "publish_dialog_chip_delay_label": "تأخير التسليم",
"subscribe_dialog_login_description": "هذا الموضوع محمي بكلمة مرور. الرجاء إدخال اسم المستخدم وكلمة المرور للاشتراك.", "subscribe_dialog_login_description": "هذا الموضوع محمي بكلمة مرور. الرجاء إدخال اسم المستخدم وكلمة المرور للاشتراك.",
"subscribe_dialog_subscribe_button_cancel": "إلغاء", "subscribe_dialog_subscribe_button_cancel": "إلغاء",
"common_back": "الرجوع", "common_back": "العودة",
"prefs_notifications_sound_play": "تشغيل الصوت المحدد", "prefs_notifications_sound_play": "تشغيل الصوت المحدد",
"prefs_notifications_min_priority_title": "أولوية دنيا", "prefs_notifications_min_priority_title": "أولوية دنيا",
"prefs_notifications_min_priority_max_only": "الأولوية القصوى فقط", "prefs_notifications_min_priority_max_only": "الأولوية القصوى فقط",
@ -329,6 +329,5 @@
"publish_dialog_attachment_limits_quota_reached": "يتجاوز الحصة، {{remainingBytes}} متبقية", "publish_dialog_attachment_limits_quota_reached": "يتجاوز الحصة، {{remainingBytes}} متبقية",
"account_basics_tier_paid_until": "تم دفع مبلغ الاشتراك إلى غاية {{date}}، وسيتم تجديده تِلْقائيًا", "account_basics_tier_paid_until": "تم دفع مبلغ الاشتراك إلى غاية {{date}}، وسيتم تجديده تِلْقائيًا",
"account_basics_tier_canceled_subscription": "تم إلغاء اشتراكك وسيتم إعادته إلى مستوى حساب مجاني بداية مِن {{date}}.", "account_basics_tier_canceled_subscription": "تم إلغاء اشتراكك وسيتم إعادته إلى مستوى حساب مجاني بداية مِن {{date}}.",
"account_delete_dialog_billing_warning": "إلغاء حسابك أيضاً يلغي اشتراكك في الفوترة فوراً ولن تتمكن من الوصول إلى لوح الفوترة بعد الآن.", "account_delete_dialog_billing_warning": "إلغاء حسابك أيضاً يلغي اشتراكك في الفوترة فوراً ولن تتمكن من الوصول إلى لوح الفوترة بعد الآن."
"nav_upgrade_banner_description": "حجز المواضيع والمزيد من الرسائل ورسائل البريد الإلكتروني والمرفقات الأكبر حجمًا"
} }

View file

@ -318,20 +318,5 @@
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} ел. писмо на ден", "account_upgrade_dialog_tier_features_emails_one": "{{emails}} ел. писмо на ден",
"account_upgrade_dialog_tier_features_emails_other": "{{emails}} ел. писма на ден", "account_upgrade_dialog_tier_features_emails_other": "{{emails}} ел. писма на ден",
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} телефонни обаждания на ден", "account_upgrade_dialog_tier_features_calls_one": "{{calls}} телефонни обаждания на ден",
"account_usage_attachment_storage_description": "{{filesize}} на файл, изтриване след {{expiry}}", "account_usage_attachment_storage_description": "{{filesize}} на файл, изтриване след {{expiry}}"
"account_upgrade_dialog_billing_contact_email": "За въпроси относно плащанията <Link>се свържете с нас</Link>.",
"account_upgrade_dialog_tier_current_label": "Текущо",
"account_upgrade_dialog_billing_contact_website": "За въпроси относно плащанията се обърнете към <Link>страницата</Link>.",
"account_upgrade_dialog_button_cancel_subscription": "Прекратяване на абонамент",
"account_upgrade_dialog_tier_features_attachment_file_size": "{{filesize}} на файл",
"account_upgrade_dialog_reservations_warning_one": "Избраното ниво разрешава по-малко резервирани теми, от колкото текущото. Преди промяна на нивото <strong>изтрийте най-малко една резервирана тема</strong>. Можете да премахвате теми в <Link>Настройки</Link>.",
"account_tokens_title": "Кодове за достъп",
"account_upgrade_dialog_tier_price_billed_monthly": "{{price}} на година. Плаща се всеки месец.",
"account_upgrade_dialog_tier_price_billed_yearly": "{{price}} плащане на година. Спестявате {{save}}.",
"account_upgrade_dialog_tier_features_attachment_total_size": "{{totalsize}} общ обем",
"account_upgrade_dialog_tier_price_per_month": "на месец",
"account_upgrade_dialog_button_pay_now": "Плащане и абониране",
"account_upgrade_dialog_tier_selected_label": "Избрано",
"account_upgrade_dialog_button_update_subscription": "Премяна на абонамент",
"account_upgrade_dialog_reservations_warning_other": "Избраното ниво разрешава по-малко резервирани теми, от колкото текущото. Преди промяна на нивото <strong>изтрийте най-малко {{count}} резервирани теми</strong>. Можете да премахвате теми в <Link>Настройки</Link>."
} }

View file

@ -39,10 +39,5 @@
"publish_dialog_attach_placeholder": "Atodi ffeil drwy URL, e.e. https://f-droid.org/F-Droid.apk", "publish_dialog_attach_placeholder": "Atodi ffeil drwy URL, e.e. https://f-droid.org/F-Droid.apk",
"notifications_click_copy_url_button": "Copio linc", "notifications_click_copy_url_button": "Copio linc",
"notifications_actions_open_url_title": "Ewch i {{url}}", "notifications_actions_open_url_title": "Ewch i {{url}}",
"publish_dialog_email_label": "Ebost", "publish_dialog_email_label": "Ebost"
"signup_form_confirm_password": "Cadarnhau cyfrinair",
"signup_form_button_submit": "Cofrestru",
"common_back": "Yn ôl",
"common_copy_to_clipboard": "Copio i'r clipfwrdd",
"signup_already_have_account": "Gyda chyfrif yn barod? Mewngofnodi!"
} }

View file

@ -25,7 +25,7 @@
"notifications_click_copy_url_title": "Link-URL in Zwischenablage kopieren", "notifications_click_copy_url_title": "Link-URL in Zwischenablage kopieren",
"publish_dialog_priority_low": "Niedrige Priorität", "publish_dialog_priority_low": "Niedrige Priorität",
"publish_dialog_message_label": "Nachricht", "publish_dialog_message_label": "Nachricht",
"action_bar_unsubscribe": "Abmelden", "action_bar_unsubscribe": "Von Thema abmelden",
"notifications_copied_to_clipboard": "In Zwischenablage kopiert", "notifications_copied_to_clipboard": "In Zwischenablage kopiert",
"notifications_loading": "Benachrichtigungen werden geladen …", "notifications_loading": "Benachrichtigungen werden geladen …",
"notifications_attachment_open_title": "Gehe zu {{url}}", "notifications_attachment_open_title": "Gehe zu {{url}}",
@ -154,7 +154,7 @@
"notifications_actions_not_supported": "Diese Aktion wird in der Web-App nicht unterstützt", "notifications_actions_not_supported": "Diese Aktion wird in der Web-App nicht unterstützt",
"notifications_actions_http_request_title": "Sende HTTP {{method}} an {{url}}", "notifications_actions_http_request_title": "Sende HTTP {{method}} an {{url}}",
"action_bar_show_menu": "Menü anzeigen", "action_bar_show_menu": "Menü anzeigen",
"action_bar_toggle_mute": "Stummschaltung an/aus", "action_bar_toggle_mute": "Stummschaltung der Benachrichtigungen an/aus",
"message_bar_show_dialog": "Dialog zur Veröffentlichung anzeigen", "message_bar_show_dialog": "Dialog zur Veröffentlichung anzeigen",
"message_bar_publish": "Benachrichtigung veröffentlichen", "message_bar_publish": "Benachrichtigung veröffentlichen",
"nav_button_connecting": "verbinde", "nav_button_connecting": "verbinde",

View file

@ -1 +0,0 @@
{}

View file

@ -272,7 +272,7 @@
"account_delete_dialog_button_submit": "Supprimer définitivement le compte", "account_delete_dialog_button_submit": "Supprimer définitivement le compte",
"account_delete_dialog_billing_warning": "Supprimer votre compte annule aussi immédiatement votre facturation. Vous n'aurez plus accès à votre tableau de bord de facturation.", "account_delete_dialog_billing_warning": "Supprimer votre compte annule aussi immédiatement votre facturation. Vous n'aurez plus accès à votre tableau de bord de facturation.",
"account_upgrade_dialog_title": "Changer le tarif du compte", "account_upgrade_dialog_title": "Changer le tarif du compte",
"account_upgrade_dialog_proration_info": "<strong>Facturation</strong> : Lors d'un changement vers un tiers payant, la différence de prix sera débitée <strong>immédiatement</strong>. En passant d'un tiers payant a gratuit, votre solde sera utilisé pour payer de futur factures.", "account_upgrade_dialog_proration_info": "<strong>Facturation</strong> : Lors d'un changement entre un plan payant et un autre, la différence de prix sera créditée ou remboursée sur la prochaine facture. Vous ne recevrez pas d'autre facture avant la fin de la prochaine période de facturation.",
"account_upgrade_dialog_reservations_warning_other": "Le tarif sélectionné autorise moins de sujets réservés que votre tarif actuel. Avant de changer de tarif, <strong>veuillez supprimer au moins {{count}} sujets réservés</strong>. Vous pouvez supprimer des sujets réservés dans les <Link>Paramètres</Link>.", "account_upgrade_dialog_reservations_warning_other": "Le tarif sélectionné autorise moins de sujets réservés que votre tarif actuel. Avant de changer de tarif, <strong>veuillez supprimer au moins {{count}} sujets réservés</strong>. Vous pouvez supprimer des sujets réservés dans les <Link>Paramètres</Link>.",
"account_upgrade_dialog_tier_features_reservations_other": "{{reservations}} sujets réservés", "account_upgrade_dialog_tier_features_reservations_other": "{{reservations}} sujets réservés",
"account_upgrade_dialog_tier_features_messages_other": "{{messages}} messages journaliers", "account_upgrade_dialog_tier_features_messages_other": "{{messages}} messages journaliers",
@ -368,17 +368,8 @@
"account_basics_phone_numbers_dialog_code_placeholder": "Ex : 123456", "account_basics_phone_numbers_dialog_code_placeholder": "Ex : 123456",
"account_basics_phone_numbers_dialog_check_verification_button": "Code de confirmarion", "account_basics_phone_numbers_dialog_check_verification_button": "Code de confirmarion",
"account_basics_phone_numbers_dialog_channel_sms": "SMS", "account_basics_phone_numbers_dialog_channel_sms": "SMS",
"account_basics_phone_numbers_dialog_channel_call": "Appeler", "account_basics_phone_numbers_dialog_channel_call": "Appel",
"account_usage_calls_none": "Aucun appels téléphoniques ne peut être fait avec ce compte", "account_usage_calls_none": "Aucun appels téléphoniques ne peut être fait avec ce compte",
"publish_dialog_call_reset": "Supprimer les appels téléphoniques", "publish_dialog_call_reset": "Supprimer les appels téléphoniques",
"publish_dialog_chip_call_label": "Appel téléphonique", "publish_dialog_chip_call_label": "Appel téléphonique"
"account_upgrade_dialog_tier_features_messages_one": "{{messages}} message journalier",
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} mail journalier",
"account_upgrade_dialog_tier_features_calls_other": "{{calls}} appels journaliers",
"account_upgrade_dialog_tier_features_no_calls": "Aucun appel",
"publish_dialog_call_item": "Appeler le numéro {{number}}",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Aucun numéro de téléphone vérifié",
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} sujet réservé",
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} appels journaliers",
"account_usage_calls_title": "Appels téléphoniques passés"
} }

View file

@ -1,384 +1 @@
{ {}
"common_cancel": "Cancelar",
"common_save": "Gardar",
"common_add": "Engadir",
"signup_disabled": "O rexistro está desactivado",
"signup_error_username_taken": "O identificador {{username}} xa está collido",
"login_title": "Accede á túa conta ntfy",
"action_bar_send_test_notification": "Enviar notificación de proba",
"action_bar_clear_notifications": "Limpar todas as notificacións",
"action_bar_unsubscribe": "Retirar subscrición",
"action_bar_profile_settings": "Axustes",
"message_bar_type_message": "Escribe aquí a mensaxe",
"notifications_copied_to_clipboard": "Copiada ao portapapeis",
"notifications_attachment_image": "Imaxe anexa",
"notifications_attachment_copy_url_title": "Copiar URL do anexo ao portapapeis",
"notifications_attachment_copy_url_button": "Copiar URL",
"notifications_attachment_open_title": "Ir a {{url}}",
"notifications_attachment_file_audio": "ficheiro de audio",
"notifications_attachment_file_app": "ficheiro de app Android",
"notifications_attachment_file_document": "outro documento",
"notifications_click_copy_url_title": "Copiar URL da ligazón ao portapapeis",
"notifications_click_copy_url_button": "Copiar ligazón",
"notifications_actions_open_url_title": "Ir a {{url}}",
"notifications_none_for_topic_description": "Para enviar notificacións a este tema, simplemente usa PUT ou POST co URL do tema.",
"notifications_no_subscriptions_description": "Preme en \"{{linktext}} para crear ou subscribirte a un tema. Após, podes enviar mensaxes vía PUT ou POST e recibirás aquí as notificacións.",
"display_name_dialog_description": "Establecer un nome alternativo para o tema que será mostrado na lista de subscrición. Isto axudará a identificar os temas que teñan nomes complicados.",
"publish_dialog_tags_label": "Etiquetas",
"publish_dialog_tags_placeholder": "Lista de etiquetas separadas por vírgulas, ex. aviso, tarefa1",
"publish_dialog_priority_label": "Prioridade",
"publish_dialog_click_label": "URL a premer",
"publish_dialog_click_placeholder": "URL que se abre ao premer na notificación",
"publish_dialog_click_reset": "Desbotar o URL a premer",
"common_back": "Atrás",
"common_copy_to_clipboard": "Copiar ao portapapeis",
"signup_title": "Crear unha conta ntfy",
"signup_form_username": "Identificador",
"signup_form_password": "Contrasinal",
"signup_form_confirm_password": "Confirmar contrasinal",
"signup_form_button_submit": "Crear conta",
"login_form_button_submit": "Acceder",
"login_link_signup": "Crear conta",
"login_disabled": "O acceso está desactivado",
"action_bar_show_menu": "Mostrar menú",
"action_bar_toggle_mute": "Acalar/Reactivar as notificacións",
"message_bar_error_publishing": "Erro ao publicar a notificación",
"message_bar_publish": "Publicar mensaxe",
"nav_topics_title": "Temas subscritos",
"nav_button_documentation": "Documentación",
"nav_button_publish_message": "Publicar notificación",
"nav_button_subscribe": "Subscribirse ao tema",
"nav_button_muted": "Notificacións acaladas",
"nav_button_connecting": "conectando",
"nav_upgrade_banner_label": "Mellorar a ntfy Pro",
"alert_not_supported_description": "O teu navegador non ten soporte para notificacións.",
"notifications_priority_x": "Prioridade {{priority}}",
"notifications_attachment_link_expires": "a ligazón caduca o {{date}}",
"notifications_attachment_link_expired": "a ligazón de descarga caducou",
"notifications_attachment_file_image": "ficheiro de imaxe",
"notifications_attachment_file_video": "ficheiro de vídeo",
"notifications_actions_not_supported": "Acción non soportada na aplicación web",
"notifications_actions_http_request_title": "Enviar HTTP {{method}} a {{url}}",
"notifications_none_for_topic_title": "Aínda non recibiches ningunha notificación para este tema.",
"reserve_dialog_checkbox_label": "Reservar tema e configurar acceso",
"notifications_loading": "Cargando notificacións…",
"publish_dialog_base_url_placeholder": "URL de servizo, ex. https://exemplo.com",
"publish_dialog_topic_label": "Nome do tema",
"publish_dialog_topic_placeholder": "Nome do tema, ex. alertas_equipo",
"publish_dialog_topic_reset": "Restablecer tema",
"publish_dialog_title_label": "Título",
"publish_dialog_title_placeholder": "Título das notificacións, ex. Alerta de reunión",
"publish_dialog_message_label": "Mensaxe",
"publish_dialog_message_placeholder": "Escribe aquí a mensaxe",
"publish_dialog_email_label": "Correo electrónico",
"signup_form_toggle_password_visibility": "Cambiar visibilidade do contrasinal",
"signup_already_have_account": "Xa tes unha conta? Accede!",
"signup_error_creation_limit_reached": "Acadouse o límite de creación de contas",
"action_bar_logo_alt": "logo ntfy",
"action_bar_settings": "Axustes",
"action_bar_account": "Conta",
"action_bar_change_display_name": "Cambiar nome público",
"action_bar_reservation_add": "Reservar tema",
"action_bar_reservation_edit": "Cambiar a reserva",
"action_bar_reservation_delete": "Desbotar a reserva",
"action_bar_reservation_limit_reached": "Acadouse o límite",
"action_bar_toggle_action_menu": "Abrir/Pechar menú de accións",
"action_bar_profile_title": "Perfil",
"action_bar_profile_logout": "Pechar sesión",
"action_bar_sign_in": "Acceder",
"action_bar_sign_up": "Crear conta",
"message_bar_show_dialog": "Mostrar diálogo para publicar",
"nav_button_all_notifications": "Todas as notificacións",
"nav_button_account": "Conta",
"nav_button_settings": "Axustes",
"nav_upgrade_banner_description": "Reserva temas, máis mensaxes e correos electrónicos así como anexos máis grandes",
"alert_grant_title": "As notificacións están desactivadas",
"alert_grant_description": "Concede permiso no navegador para mostrar notificacións de escritorio.",
"alert_grant_button": "Conceder agora",
"alert_not_supported_title": "Non hai soporte para notificacións",
"alert_not_supported_context_description": "Só hai soporte para notificacións ao usar HTTPS. Esta é unha limitación da <mdnLink>API de Notificacións</mdnLink>.",
"notifications_list": "Lista de notificacións",
"notifications_list_item": "Notificación",
"notifications_mark_read": "Marcar como lida",
"notifications_delete": "Eliminar",
"notifications_tags": "Etiquetas",
"notifications_new_indicator": "Nova notificación",
"notifications_attachment_open_button": "Abrir anexo",
"notifications_click_open_button": "Abrir ligazón",
"notifications_none_for_any_title": "Non recibiches ningunha notificación.",
"notifications_none_for_any_description": "Para enviar notificacións ao tema, simplemente usa PUT ou POST ao URL do tema. Aquí tes un exemplo usando un dos teus temas.",
"notifications_no_subscriptions_title": "Semella que aínda non tes subscricións.",
"notifications_example": "Exemplo",
"display_name_dialog_title": "Cambiar nonme público",
"display_name_dialog_placeholder": "Nome público",
"publish_dialog_title_topic": "Publicar en {{topic}}",
"publish_dialog_title_no_topic": "Publicar notificación",
"publish_dialog_progress_uploading": "Enviando…",
"publish_dialog_progress_uploading_detail": "Enviando {{loaded}}/{{total}} ({{percent}}%) …",
"publish_dialog_message_published": "Notificación publicada",
"publish_dialog_attachment_limits_file_and_quota_reached": "supera o límite de ficheiros e cota {{fileSizeLimit}}, quedan {{remainingBytes}}",
"publish_dialog_attachment_limits_file_reached": "supera o límite para ficheiros {{fileSizeLimit}}",
"publish_dialog_attachment_limits_quota_reached": "supera a cota, quedan {{remainingBytes}}",
"publish_dialog_emoji_picker_show": "Elixe emoji",
"publish_dialog_priority_min": "Prioridade Mínima",
"publish_dialog_priority_low": "Prioridade baixa",
"publish_dialog_priority_default": "Prioridade por defecto",
"publish_dialog_priority_high": "Prioridade alta",
"publish_dialog_priority_max": "Prioridade Máxima",
"publish_dialog_base_url_label": "URL do servizo",
"notifications_more_details": "Para máis información, visita o <websiteLink>sitio web</websiteLink> ou le a <docsLink>documentación</docsLink>.",
"publish_dialog_call_label": "Chamada de teléfono",
"publish_dialog_call_reset": "Retirar chamada de teléfono",
"publish_dialog_delay_placeholder": "Adiar a entrega, ex. {{unixTimestamp}}, {{relativeTime}}, ou \"{{naturalLanguage}}\" (Só en inglés)",
"publish_dialog_other_features": "Outras características:",
"publish_dialog_chip_click_label": "Premer en URL",
"publish_dialog_chip_email_label": "Reenvío por correo",
"publish_dialog_chip_call_label": "Chamada de teléfono",
"publish_dialog_chip_attach_url_label": "Anexar ficheiro por URL",
"publish_dialog_button_cancel_sending": "Cancelar o envío",
"publish_dialog_button_cancel": "Cancelar",
"publish_dialog_button_send": "Enviar",
"publish_dialog_attached_file_title": "Ficheiro anexo:",
"publish_dialog_attached_file_filename_placeholder": "Nome do ficheiro anexo",
"publish_dialog_drop_file_here": "Soltar aquí o ficheiro",
"emoji_picker_search_placeholder": "Buscar emoji",
"subscribe_dialog_subscribe_title": "Subscribirse a un tema",
"publish_dialog_call_item": "Número de teléfono {{number}}",
"publish_dialog_email_placeholder": "Enderezo ao que reenviar a notificación, ex. xoana@exemplo.com",
"publish_dialog_email_reset": "Retirar reenvío ao correo",
"publish_dialog_attach_label": "URL do anexo",
"publish_dialog_attach_placeholder": "Anexa un ficheiro por URL, ex. https://f-droid.org/F-Droid.apk",
"publish_dialog_attach_reset": "Retirar URL do anexo",
"publish_dialog_filename_placeholder": "Nome do ficheiro anexo",
"publish_dialog_filename_label": "Nome do ficheiro",
"publish_dialog_delay_label": "Adiar",
"publish_dialog_delay_reset": "Retirar o adiadamento da entrega",
"publish_dialog_chip_attach_file_label": "Anexar ficheiro local",
"publish_dialog_chip_delay_label": "Entrega adiada",
"publish_dialog_chip_topic_label": "Cambiar tema",
"publish_dialog_details_examples_description": "Para ver exemplos e unha descrición polo miúdo das ferramentas de envío, le a <docsLink>documentación</docsLink>.",
"publish_dialog_checkbox_publish_another": "Publicar outra",
"emoji_picker_search_clear": "Limpar busca",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Números de teléfono non verificados",
"publish_dialog_attached_file_remove": "Retirar ficheiro anexo",
"account_upgrade_dialog_tier_features_no_calls": "Sen chamadas",
"account_upgrade_dialog_billing_contact_email": "Para preguntas sobre pagamentos, <Link>contacta con nós</Link> directamente.",
"account_tokens_dialog_title_create": "Crear token de acceso",
"prefs_reservations_dialog_title_edit": "Editar tema reservado",
"priority_default": "por defecto",
"prefs_notifications_min_priority_title": "Prioridade mínima",
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} chamadas de teléfono diarias",
"account_upgrade_dialog_tier_current_label": "Actual",
"account_tokens_table_token_header": "Token",
"prefs_notifications_delete_after_never": "Nunca",
"prefs_users_description": "Engadir/eliminar usuarias dos temas protexidos. Ten en conta que as credenciais gárdanse na almacenaxe local do navegador.",
"subscribe_dialog_subscribe_description": "Os temas poderían non estar proxetidos con contrasinal, así que elixe un nome complicado de adiviñar. Unha vez subscrita, podes PUT/POST notificacións.",
"account_upgrade_dialog_interval_yearly_discount_save_up_to": "aforro ata un {{discount}}%",
"account_tokens_dialog_label": "Etiqueta, ex. notificación de Radarr",
"account_tokens_table_expires_header": "Caducidade",
"account_upgrade_dialog_proration_info": "<strong>Axuste</strong>: ao mellorar a un plan de pagamento superior, a diferencia vaise <strong>cobrar inmediatamente</strong>. Se degradas a conta a un plan inferior a diferencia usarase para pagar futuros períodos de pagamento.",
"prefs_reservations_dialog_access_label": "Acceso",
"account_usage_attachment_storage_title": "Almacenaxe dos anexos",
"prefs_users_dialog_username_label": "Identificador, ex. xoana",
"prefs_reservations_table_not_subscribed": "Non subscrita",
"account_upgrade_dialog_tier_features_emails_other": "{{emails}} correos diarios",
"prefs_notifications_min_priority_max_only": "Só prioridade máxima",
"account_upgrade_dialog_tier_features_calls_other": "{{calls}} chamadas de teléfono diarias",
"prefs_notifications_sound_description_some": "As notificacións sonan co ton {{sound}} ao chegar",
"prefs_reservations_edit_button": "Editar acceso ao tema",
"account_tokens_dialog_expires_never": "O token non caduca",
"subscribe_dialog_login_title": "Require inciar sesión",
"account_tokens_dialog_expires_x_days": "O token caduca en {{days}} días",
"prefs_reservations_table_everyone_read_only": "Podo publicar e subscribirme, calquera pode subscribirse",
"prefs_reservations_table_everyone_deny_all": "Só eu podo publicar e subscribirme",
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} tema reservado",
"subscribe_dialog_login_button_login": "Acceder",
"account_upgrade_dialog_tier_features_no_reservations": "Sen temas reservados",
"prefs_users_table_cannot_delete_or_edit": "Non se pode eliminar ou editar unha usuaria coa sesión iniciada",
"prefs_notifications_delete_after_three_hours_description": "As notificacións autoelimínanse após tres horas",
"prefs_notifications_delete_after_three_hours": "Após tres horas",
"prefs_notifications_min_priority_description_x_or_higher": "Mostrar as notificacións se a prioridade é {{number}} {{name}} ou superior",
"reservation_delete_dialog_description": "Ao eliminar a reserva cedes a propiedade do tema, e permites que outras persoas poidan reservalo. Podes manter ou eliminar as mensaxes e anexos existentes.",
"prefs_reservations_table_everyone_read_write": "Calquera pode publicar e subscribirse",
"prefs_reservations_dialog_title_delete": "Eliminar a reserva do tema",
"prefs_users_table": "Táboa de usuarias",
"prefs_reservations_table_topic_header": "Tema",
"reservation_delete_dialog_submit_button": "Eliminar a reserva",
"prefs_reservations_limit_reached": "Acadaches o límite de temas que podes reservar.",
"account_upgrade_dialog_interval_monthly": "Mensual",
"prefs_users_add_button": "Engadir usuaria",
"account_upgrade_dialog_tier_features_messages_other": "{{messages}} mensaxes diarias",
"prefs_appearance_language_title": "Idioma",
"prefs_notifications_delete_after_one_day_description": "As notificacións autoelimínanse após un día",
"account_tokens_table_never_expires": "Non caduca",
"account_tokens_delete_dialog_title": "Desbotar token de acceso",
"prefs_notifications_delete_after_one_month": "Após un mes",
"account_tokens_delete_dialog_description": "Antes de borrar o token de acceso mira que ningunha aplicación ou programa o está usando. <strong>Esta acción non pode desfacerse</strong>.",
"account_upgrade_dialog_button_cancel": "Cancelar",
"account_tokens_table_label_header": "Etiqueta",
"account_upgrade_dialog_billing_contact_website": "Para preguntas sobre pagamentos, vai ao noso <Link>sitiio web</Link>.",
"prefs_notifications_delete_after_never_description": "As notificacións non se eliminarán nunca automáticamente",
"account_upgrade_dialog_tier_features_reservations_other": "{{reservations}} temas reservados",
"prefs_notifications_sound_description_none": "As notificacións non reproducen un ton ao chegar",
"account_tokens_description": "Usar tokens de acceso ao publicar e subscribirte a través da API de ntfy, así non tes que enviar as credenciais. Le a <Link>documentación</Link> para saber máis.",
"prefs_reservations_table": "Táboa cos temas reservados",
"account_upgrade_dialog_button_cancel_subscription": "Cancelar subscrición",
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} correo diario",
"account_upgrade_dialog_tier_features_attachment_file_size": "{{filesize}} por ficheiro",
"prefs_reservations_description": "Podes reservar nomes de temas para uso personal. Ao reservar un tema tes a propiedade sobre del, e permíteche definir os permisos de acceso para outras usuarias sobre o tema.",
"prefs_users_description_no_sync": "Usuarias e contrasinais non están sincronizados coa túa conta.",
"account_tokens_dialog_title_edit": "Editar token de acceso",
"prefs_users_table_base_url_header": "URL do servizo",
"account_upgrade_dialog_tier_features_messages_one": "{{mensaxes}} mensaxe diaria",
"account_upgrade_dialog_reservations_warning_one": "O nivel seleccionado permite reservar menos temas que o nivel actual. Antes de cambiar de nivel, <strong>elimina unha reserva polo menos</strong>. Podes eliminar as reservas nos <Link>Axustes</Link>.",
"prefs_users_table_user_header": "Usuaria",
"error_boundary_stack_trace": "Trazas do problema",
"prefs_users_dialog_password_label": "Contrasinal",
"prefs_notifications_delete_after_one_week": "Após unha semana",
"prefs_reservations_delete_button": "Restablecer acceso ao tema",
"prefs_notifications_delete_after_one_week_description": "As notificacións autoelimínanse após unha semana",
"error_boundary_unsupported_indexeddb_description": "A app ntfy web precisa a función IndexedDB, e o teu navegador non ten soporte para IndexedDB no modo privado.<br/><br/>Aínda que é unha mágoa, tampouco ten moito senso usar a app ntfy web en modo privado, porque todo se garda na almacenaxe do navegador. Podes aprender máis sobre isto <githubLink>neste tema de GitHub</githubLink>, ou comentarnos o que che parece en <discordLink>Discord</discordLink> ou <matrixLink>Matrix</matrixLink>.",
"subscribe_dialog_subscribe_button_cancel": "Cancelar",
"account_basics_tier_description": "O nivel da túa conta",
"prefs_reservations_dialog_title_add": "Reservar tema",
"account_upgrade_dialog_cancel_warning": "Isto vai <strong>cancelar a túa subscrición</strong>, e degradar a túa conta o {{date}}. Nesa data, as reservas de temas así como as mensaxes na caché do servidor <strong>van ser eliminadas</strong>.",
"prefs_notifications_sound_title": "Ton da notificación",
"prefs_notifications_min_priority_default_and_higher": "Prioridade por defecto e superior",
"prefs_reservations_table_access_header": "Acceso",
"account_tokens_table_copied_to_clipboard": "Copiouse o token de acceso",
"account_tokens_dialog_expires_x_hours": "O token caduca en {{hours}} horas",
"prefs_users_edit_button": "Editar usuaria",
"account_upgrade_dialog_title": "Cambiar facturación da conta",
"priority_low": "baixa",
"prefs_reservations_table_click_to_subscribe": "Preme para subscribirte",
"error_boundary_description": "Isto non debería pasar. Lamentámolo. <br/>Se tes un minuto, <githubLink>informa en GitHub</githubLink>, ou fáinolo saber en <discordLink>Discord</discordLink> ou <matrixLink>Matrix</matrixLink>.",
"priority_min": "min",
"prefs_notifications_min_priority_description_any": "Mostrar todas as notificacións, obviando a prioridade",
"error_boundary_gathering_info": "Obter máis info…",
"error_boundary_unsupported_indexeddb_title": "Non hai soporte para a navegación privada",
"prefs_notifications_delete_after_one_day": "Após un día",
"error_boundary_title": "vaite!, ntfy fallou",
"reservation_delete_dialog_action_keep_description": "As mensaxes e anexos que están no servidor serán visibles públicamente para quen saiba o nome do tema.",
"prefs_reservations_add_button": "Engadir tema reservado",
"prefs_reservations_title": "Temas reservados",
"prefs_reservations_dialog_description": "Ao reservar un tema tes a propiedade sobre el, e permíteche definir os permisos de acceso para outras usuarias.",
"account_tokens_delete_dialog_submit_button": "Eliminar definitivamente o token",
"prefs_notifications_title": "Notificacións",
"account_tokens_title": "Tokens de acceso",
"prefs_reservations_dialog_topic_label": "Tema",
"prefs_users_title": "Xestionar usuarias",
"account_upgrade_dialog_tier_price_billed_monthly": "{{price}} anual. Pagamento mensual.",
"account_tokens_dialog_expires_unchanged": "Deixar a data de caducidade sen cambiar",
"error_boundary_button_copy_stack_trace": "Copiar trazas do problema",
"account_tokens_dialog_title_delete": "Eliminar token de acceso",
"reservation_delete_dialog_action_keep_title": "Manter as mensaxes e anexos gardados",
"prefs_notifications_sound_no_sound": "Sen ton",
"account_upgrade_dialog_interval_yearly": "Anual",
"account_upgrade_dialog_button_redirect_signup": "Crea unha conta",
"account_tokens_dialog_button_cancel": "Cancelar",
"account_upgrade_dialog_tier_price_billed_yearly": "{{price}} cobrado anualmente. Aforro {{save}}.",
"prefs_notifications_min_priority_high_and_higher": "Prioridade alta e superior",
"priority_max": "máx",
"prefs_users_delete_button": "Eliminar usuaria",
"prefs_notifications_min_priority_any": "Calquera prioridade",
"account_tokens_dialog_expires_label": "O token caduca o",
"prefs_notifications_delete_after_title": "Desbotar notificacións",
"account_upgrade_dialog_interval_yearly_discount_save": "aforro {{discount}}%",
"prefs_users_dialog_title_edit": "Editar usuaria",
"prefs_notifications_min_priority_low_and_higher": "Prioridade baixa e superior",
"account_tokens_dialog_button_update": "Actualizar token",
"account_upgrade_dialog_tier_features_attachment_total_size": "{{totalsize}} almacenaxe total",
"prefs_reservations_table_everyone_write_only": "Podo publicar e subscribirme, calquera pode publicar",
"prefs_appearance_title": "Aparencia",
"account_tokens_table_cannot_delete_or_edit": "Non se pode editar ou desbotar o token da sesión actual",
"prefs_notifications_sound_play": "Reproducir ton seleccionado",
"account_tokens_table_last_access_header": "Último acceso",
"account_tokens_table_last_origin_tooltip": "Desde o enderezo IP {{ip}}, preme para detalles",
"account_upgrade_dialog_tier_price_per_month": "mes",
"account_tokens_table_current_session": "Sesión do navegador actual",
"account_upgrade_dialog_button_pay_now": "Paga e subscríbete",
"reservation_delete_dialog_action_delete_title": "Eliminar mensaxes e anexos gardados",
"reservation_delete_dialog_action_delete_description": "As mensaxes e anexos vanse borrar definitivamente. Esta acción non ten volta.",
"prefs_notifications_delete_after_one_month_description": "As notificacións autoelimínanse após un mes",
"prefs_users_dialog_base_url_label": "URL do servizo, ex. https://ntfy.sh",
"account_upgrade_dialog_tier_selected_label": "Seleccionado",
"account_upgrade_dialog_button_update_subscription": "Actualizar subscrición",
"priority_high": "alta",
"account_delete_dialog_billing_warning": "Ao eliminar a conta tamén cancelas o pagamento das subscricións. Non poderás volver acceder ao taboleiro de pagamentos.",
"prefs_notifications_min_priority_description_max": "Mostrar notificacións se a prioridade é 5 (máx)",
"account_upgrade_dialog_reservations_warning_other": "O nivel seleccionado permite reservar menos temas que o nivel actual. Antes de cambiar de nivel, <strong>elimina {{count}} reservas polo menos</strong>. Podes eliminar as reservas nos <Link>Axustes</Link>.",
"prefs_users_dialog_title_add": "Engadir usuaria",
"account_tokens_dialog_button_create": "Crear token",
"account_tokens_table_create_token_button": "Crear token de acceso",
"account_basics_tier_interval_monthly": "mensual",
"account_basics_tier_canceled_subscription": "A sua suscripción foi cancelada e vostede será degradado a unha conta gratuita o {{date}}.",
"account_basics_password_dialog_current_password_incorrect": "Contrasinal incorrecto",
"account_basics_phone_numbers_dialog_number_label": "Número de teléfono",
"account_basics_password_dialog_button_submit": "Modificar contrasinal",
"account_basics_username_title": "Usuario",
"account_basics_phone_numbers_dialog_check_verification_button": "Código de confirmación",
"account_usage_messages_title": "Mesaxes publicados",
"account_basics_phone_numbers_dialog_verify_button_sms": "Enviar SMS",
"account_basics_tier_change_button": "Cambiar",
"account_basics_phone_numbers_dialog_description": "Para usar a característica de chamadas de teléfono, vostede debe engadir e verificar ao menos un número de teléfono. A verificación pode ser realizada vía SMS ou a través de chamada.",
"account_delete_title": "Borrar conta",
"account_delete_dialog_label": "Contrasinal",
"account_basics_tier_admin_suffix_with_tier": "(con tier {{tier}})",
"subscribe_dialog_login_username_label": "Nome de usuario, ex. phil",
"subscribe_dialog_error_user_not_authorized": "Usuario {{username}} non autorizado",
"account_basics_title": "Conta",
"account_basics_phone_numbers_no_phone_numbers_yet": "Aínda non hay números de teléfono",
"subscribe_dialog_subscribe_button_generate_topic_name": "Xerar nome",
"subscribe_dialog_login_password_label": "Contrasinal",
"subscribe_dialog_subscribe_button_subscribe": "Subscribirse",
"account_basics_phone_numbers_dialog_title": "Engadir número de teléfono",
"account_basics_username_admin_tooltip": "É vostede Admin",
"account_delete_dialog_description": "Isto borrará permanentemente a túa conta, incluido todos os datos almacenados no servidor. Despois do borrado, o teu nome de usuario non estará dispoñible durante 7 días. Se realmente queres proceder, por favor confirme co seu contrasinal na caixa inferior.",
"account_usage_reservations_none": "Non hai temas reservados para esta conta",
"subscribe_dialog_subscribe_topic_placeholder": "Nome do tema, ex. phil_alertas",
"account_usage_title": "Uso",
"account_basics_tier_upgrade_button": "Mexorar a Pro",
"subscribe_dialog_error_topic_already_reserved": "Tema xa reservado",
"account_basics_tier_admin_suffix_no_tier": "(sen tier)",
"account_basics_tier_payment_overdue": "O pago está retrasado. Por favor, revise o seu método de pago o a súa conta será degradada pronto.",
"account_basics_phone_numbers_description": "Para notificacións telefónicas",
"account_basics_tier_free": "De balde",
"account_basics_tier_admin": "Admin",
"account_delete_dialog_button_cancel": "Cancelar",
"account_basics_password_description": "Modificar o contrasinal da conta",
"account_usage_calls_title": "Chamadas realizadas",
"account_basics_tier_basic": "Básico",
"account_basics_phone_numbers_copied_to_clipboard": "Número de teléfono copiado no portapapeis",
"account_basics_tier_title": "Tipo de conta",
"account_usage_cannot_create_portal_session": "Non foi posible abrir o portal de pagos",
"account_delete_description": "Borrar permanentemente a túa conta",
"account_basics_phone_numbers_dialog_number_placeholder": "ex. +1222333444",
"account_basics_phone_numbers_dialog_code_placeholder": "ex. 123456",
"account_basics_tier_manage_billing_button": "Xestionar pagos",
"account_basics_username_description": "Ei, ese eres ti ❤",
"account_basics_password_dialog_confirm_password_label": "Confirmar contrasinal",
"account_basics_tier_interval_yearly": "anual",
"account_delete_dialog_button_submit": "Borrar permanentemente a conta",
"account_basics_phone_numbers_dialog_channel_call": "Chamada",
"account_basics_password_title": "Contrasinal",
"account_basics_password_dialog_new_password_label": "Novo contrasinal",
"account_usage_of_limit": "de {{limit}}",
"subscribe_dialog_error_user_anonymous": "anónimo",
"account_usage_basis_ip_description": "Estadísticas de uso e límites para esta conta están basados na sua IP, polo que poden estar compartidos con outros usuarios. Os limites mostrados son aproximados, basados nos ratios de limite existentes.",
"account_basics_password_dialog_title": "Modificar contrasinal",
"account_usage_limits_reset_daily": "Límite de uso é reiniciado diariamente a medianoite (UTC(",
"account_usage_unlimited": "Sen límites",
"account_basics_phone_numbers_title": "Números de teléfono",
"account_basics_password_dialog_current_password_label": "Contrasinal actual",
"subscribe_dialog_subscribe_base_url_label": "URL do servizo",
"account_usage_reservations_title": "Temas reservados",
"account_usage_calls_none": "Non se poden realizar chamadas con esta conta",
"subscribe_dialog_subscribe_use_another_label": "Usar outro servidor",
"account_basics_phone_numbers_dialog_code_label": "Código de verificación",
"account_basics_tier_paid_until": "Suscripción pagada ata {{date}}, e vaise auto-renovar",
"account_usage_attachment_storage_description": "{{filesize}} por arquivo, borrado despois de {{expiry}}",
"account_basics_phone_numbers_dialog_verify_button_call": "Chámame",
"account_usage_emails_title": "Emails enviados",
"account_basics_phone_numbers_dialog_channel_sms": "SMS",
"subscribe_dialog_login_description": "Este tema está protexido por contrasinal. Por favor, introduza o usuario e contrasinal para subscribirse."
}

View file

@ -267,42 +267,5 @@
"publish_dialog_chip_call_label": "Chiamata telefonica", "publish_dialog_chip_call_label": "Chiamata telefonica",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Nessun numero verificato", "publish_dialog_chip_call_no_verified_numbers_tooltip": "Nessun numero verificato",
"account_basics_phone_numbers_title": "Numeri di telefono", "account_basics_phone_numbers_title": "Numeri di telefono",
"account_basics_phone_numbers_dialog_description": "Per usare la funzionalità di notifica tramite chiamata telefonica, devi aggiungere e verificare almeno un numero di telefono. La verifica può essere fatta tramite SMS o chiamata telefonica.", "account_basics_phone_numbers_dialog_description": "Per usare la funzionalità di notifica tramite chiamata telefonica, devi aggiungere e verificare almeno un numero di telefono. La verifica può essere fatta tramite SMS o chiamata telefonica."
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} topic riservato",
"account_upgrade_dialog_billing_contact_email": "Per domande di fatturazione, <Link>contattaci</Link> direttamente.",
"account_upgrade_dialog_tier_current_label": "Attuale",
"account_basics_phone_numbers_dialog_number_label": "Numero di telefono",
"account_basics_phone_numbers_dialog_check_verification_button": "Conferma codice",
"account_basics_phone_numbers_dialog_verify_button_sms": "Invia SMS",
"account_basics_phone_numbers_no_phone_numbers_yet": "Ancora nessun numero di telefono",
"account_basics_phone_numbers_dialog_title": "Aggiungi un numero di telefono",
"account_upgrade_dialog_button_cancel": "Cancella",
"account_upgrade_dialog_billing_contact_website": "Per domande di fatturazione, visita per favore in nostro <Link>sito</Link>.",
"account_upgrade_dialog_button_cancel_subscription": "Cancella iscrizione",
"account_basics_phone_numbers_description": "Per notifiche via chiamata",
"account_basics_phone_numbers_copied_to_clipboard": "Numero di telefono copiato negli appunti",
"account_basics_phone_numbers_dialog_number_placeholder": "p. e. +391234567890",
"account_basics_phone_numbers_dialog_code_placeholder": "p. e. 123456",
"account_tokens_title": "Token d'accesso",
"account_upgrade_dialog_tier_price_billed_monthly": "{{price}} all'anno. Addebitato annualmente.",
"account_basics_phone_numbers_dialog_channel_call": "Chiama",
"account_upgrade_dialog_button_redirect_signup": "Iscriviti ora",
"account_upgrade_dialog_tier_price_billed_yearly": "{{price}} addebitato annualmente. Risparmia {{save}}.",
"account_upgrade_dialog_tier_price_per_month": "mese",
"account_upgrade_dialog_button_pay_now": "Paga ora e isciviti",
"account_basics_phone_numbers_dialog_code_label": "Codice di verifica",
"account_basics_phone_numbers_dialog_verify_button_call": "Chiamami",
"account_basics_phone_numbers_dialog_channel_sms": "SMS",
"account_upgrade_dialog_tier_selected_label": "Selezionato",
"account_upgrade_dialog_button_update_subscription": "Aggiorna iscrizione",
"account_usage_attachment_storage_title": "Archivio allegati",
"account_delete_dialog_description": "Il tuo account sarà permanentemente cancellato assieme a tutti i tuoi dati presenti sul server. Dopo la cancellazione, la tua username non sarà disponibile per 7 giorni. Se desideri davvero procedere, inserisci la tua password nella seguente casella.",
"account_delete_dialog_button_cancel": "Annulla",
"account_usage_calls_title": "Chiamate effettuate",
"account_delete_description": "Elimina permanentemente il tuo account",
"account_delete_dialog_button_submit": "Elimina il tuo account permanentemente",
"account_usage_basis_ip_description": "Le statistiche di utilizzo e i limiti per questo account sono basati sul tuo indirizzo IP, quindi potrebbero essere in condivisione con altri utenti. I limiti mostrati sopra sono approssimazioni basate sui limiti esistenti.",
"account_usage_calls_none": "Questo account non può effettuare chiamate",
"account_delete_dialog_billing_warning": "Eliminando il tuo account perderai immediatamente il tuo abbonamento. Non potrai più accedere alla dashboard di fatturazione.",
"account_delete_dialog_label": "Password"
} }

View file

@ -190,10 +190,5 @@
"error_boundary_unsupported_indexeddb_title": "Privat surfing støttes ikke", "error_boundary_unsupported_indexeddb_title": "Privat surfing støttes ikke",
"action_bar_account": "Konto", "action_bar_account": "Konto",
"action_bar_profile_settings": "Innstillinger", "action_bar_profile_settings": "Innstillinger",
"nav_button_account": "Konto", "nav_button_account": "Konto"
"signup_title": "Opprett en ntfy konto",
"signup_form_username": "Brukernavn",
"signup_form_password": "Passord",
"signup_form_button_submit": "Meld deg på",
"signup_form_confirm_password": "Bekreft passord"
} }

View file

@ -191,33 +191,10 @@
"error_boundary_unsupported_indexeddb_description": "O ntfy web app precisa do IndexedDB para funcionar, e seu navegador não suporta IndexedDB no modo de navegação privada.<br/><br/>Embora isso seja lamentável, também não faz muito sentido usar o ntfy web app no modo de navegação privada de qualquer maneira, porque tudo é armazenado no armazenamento do navegador. Você pode ler mais sobre isso <githubLink>nesta edição do GitHub</githubLink>, ou falar conosco em <discordLink>Discord</discordLink> ou <matrixLink>Matrix</matrixLink>.", "error_boundary_unsupported_indexeddb_description": "O ntfy web app precisa do IndexedDB para funcionar, e seu navegador não suporta IndexedDB no modo de navegação privada.<br/><br/>Embora isso seja lamentável, também não faz muito sentido usar o ntfy web app no modo de navegação privada de qualquer maneira, porque tudo é armazenado no armazenamento do navegador. Você pode ler mais sobre isso <githubLink>nesta edição do GitHub</githubLink>, ou falar conosco em <discordLink>Discord</discordLink> ou <matrixLink>Matrix</matrixLink>.",
"action_bar_reservation_add": "Reserve topic", "action_bar_reservation_add": "Reserve topic",
"action_bar_reservation_edit": "Change reservation", "action_bar_reservation_edit": "Change reservation",
"signup_disabled": "Registrar está desativado", "signup_disabled": "Signup is disabled",
"signup_error_username_taken": "Usuário {{username}} já existe", "signup_error_username_taken": "Username {{username}} is already taken",
"signup_error_creation_limit_reached": "Limite de criação de contas atingido", "signup_error_creation_limit_reached": "Account creation limit reached",
"action_bar_reservation_delete": "Remover reserva", "action_bar_reservation_delete": "N",
"action_bar_account": "Conta", "action_bar_account": "Account",
"action_bar_change_display_name": "Change display name", "action_bar_change_display_name": "Change display name"
"common_copy_to_clipboard": "Copiar para área de transferência",
"login_link_signup": "Registrar",
"login_title": "Entrar na sua conta ntfy",
"login_form_button_submit": "Entrar",
"login_disabled": "Login está desabilitado",
"action_bar_reservation_limit_reached": "Limite atingido",
"action_bar_profile_title": "Perfil",
"action_bar_profile_settings": "Configurações",
"action_bar_profile_logout": "Sair",
"action_bar_sign_in": "Entrar",
"action_bar_sign_up": "Registrar",
"nav_button_account": "Conta",
"signup_title": "Criar uma conta ntfy",
"signup_form_username": "Usuário",
"signup_form_password": "Senha",
"signup_form_confirm_password": "Confirmar senha",
"signup_form_button_submit": "Registrar",
"account_basics_phone_numbers_title": "Telefones",
"signup_form_toggle_password_visibility": "Ativar visibilidade de senha",
"signup_already_have_account": "Já possui uma conta? Entrar!",
"nav_upgrade_banner_label": "Atualizar para ntfy Pro",
"account_basics_phone_numbers_dialog_description": "Para usar o recurso de notificação de chamada, é necessários adicionar e verificar pelo menos um número de telefone. A verificação pode ser feita por SMS ou chamada telefônica.",
"account_basics_phone_numbers_description": "Para notificações de chamada telefônica"
} }

View file

@ -354,7 +354,7 @@
"account_upgrade_dialog_billing_contact_email": "По вопросам оплаты, пожалуйста <Link>свяжитесь с нами</Link>.", "account_upgrade_dialog_billing_contact_email": "По вопросам оплаты, пожалуйста <Link>свяжитесь с нами</Link>.",
"account_upgrade_dialog_billing_contact_website": "По вопросам оплаты, пожалуйста обратитесь к нашему <Link>сайту</Link>.", "account_upgrade_dialog_billing_contact_website": "По вопросам оплаты, пожалуйста обратитесь к нашему <Link>сайту</Link>.",
"publish_dialog_call_reset": "Удалить вызов", "publish_dialog_call_reset": "Удалить вызов",
"account_basics_phone_numbers_dialog_description": "Для того что бы использовать возможность уведомлений о вызовах, нужно добавить и проверить хотя бы один номер телефона. Проверить можно используя SMS или звонок.", "account_basics_phone_numbers_dialog_description": "Для использования уведомлений необходимо добавить и подтвердить хотя бы один номер телефона. Проверить можно используя SMS или звонок.",
"account_basics_phone_numbers_dialog_title": "Добавить номер телефона", "account_basics_phone_numbers_dialog_title": "Добавить номер телефона",
"account_basics_phone_numbers_dialog_number_placeholder": "например +1222333444", "account_basics_phone_numbers_dialog_number_placeholder": "например +1222333444",
"account_basics_phone_numbers_dialog_code_placeholder": "например 123456", "account_basics_phone_numbers_dialog_code_placeholder": "например 123456",
@ -363,22 +363,5 @@
"account_usage_calls_none": "Невозможно совершать вызовы с этим аккаунтом", "account_usage_calls_none": "Невозможно совершать вызовы с этим аккаунтом",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Нет проверенных номеров", "publish_dialog_chip_call_no_verified_numbers_tooltip": "Нет проверенных номеров",
"account_basics_phone_numbers_copied_to_clipboard": "Номер телефона скопирован в буфер обмена", "account_basics_phone_numbers_copied_to_clipboard": "Номер телефона скопирован в буфер обмена",
"account_upgrade_dialog_tier_features_no_calls": "Нет вызовов", "account_upgrade_dialog_tier_features_no_calls": "Нет вызовов"
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} ежедневный звонок",
"account_basics_phone_numbers_dialog_number_label": "Номер телефона",
"account_basics_phone_numbers_dialog_check_verification_button": "Подтвердить код",
"account_upgrade_dialog_tier_features_calls_other": "{{calls}} ежедневных звонков",
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} зарезервированная тема",
"account_basics_phone_numbers_no_phone_numbers_yet": "Телефонных номеров пока нет",
"publish_dialog_chip_call_label": "Звонок",
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} ежедневное письмо",
"account_upgrade_dialog_tier_features_messages_one": "{{messages}} ежедневное сообщения",
"account_basics_phone_numbers_description": "Для уведомлений о телефонных звонках",
"publish_dialog_call_label": "Звонок",
"account_basics_phone_numbers_dialog_channel_call": "Позвонить",
"account_basics_phone_numbers_title": "Номера телефонов",
"account_basics_phone_numbers_dialog_code_label": "Проверочный код",
"account_basics_phone_numbers_dialog_verify_button_call": "Позвонить мне",
"publish_dialog_call_item": "Вызов телефонного номера {{number}}",
"account_basics_phone_numbers_dialog_channel_sms": "SMS"
} }

View file

@ -1,384 +0,0 @@
{
"common_save": "Uložiť",
"common_back": "Späť",
"common_copy_to_clipboard": "Kopírovať do schránky",
"signup_title": "Vytvoriť ntfy účet",
"signup_form_username": "Používateľské meno",
"signup_form_confirm_password": "Potvrdenie hesla",
"signup_form_button_submit": "Zaregistrovať sa",
"signup_form_toggle_password_visibility": "Prepnúť viditeľnosť hesla",
"signup_error_username_taken": "Používateľské meno {{username}} je už obsadené",
"login_form_button_submit": "Prihlásiť sa",
"login_disabled": "Prihlásenie je zakázané",
"action_bar_logo_alt": "ntfy logo",
"action_bar_settings": "Nastavenia",
"action_bar_account": "Účet",
"action_bar_sign_in": "Prihlásiť sa",
"action_bar_profile_settings": "Nastavenia",
"action_bar_reservation_edit": "Zmeniť rezerváciu",
"action_bar_unsubscribe": "Odhlásiť odber",
"action_bar_toggle_mute": "Stlmiť/zrušiť stlmenie upozornení",
"action_bar_toggle_action_menu": "Otvoriť/zavrieť akčné menu",
"action_bar_profile_title": "Profil",
"nav_button_settings": "Nastavenia",
"nav_button_account": "Účet",
"message_bar_show_dialog": "Zobraziť okno pre odosielanie oznámení",
"message_bar_publish": "Zverejniť správu",
"nav_topics_title": "Odoberané témy",
"nav_button_all_notifications": "Všetky oznámenia",
"alert_grant_description": "Udeliť prehliadaču povolenie na zobrazovanie oznámení na ploche.",
"alert_not_supported_context_description": "Oznámenia sú podporované len cez HTTPS. Ide o obmedzenie rozhrania <mdnLink>Notifications API</mdnLink>.",
"notifications_list": "Zoznam oznámení",
"notifications_list_item": "Oznámenie",
"notifications_mark_read": "Označiť ako prečítané",
"notifications_delete": "Zmazať",
"notifications_copied_to_clipboard": "Skopírované do schránky",
"notifications_tags": "Štítky",
"notifications_priority_x": "Priorita {{priority}}",
"notifications_new_indicator": "Nové oznámenie",
"notifications_attachment_image": "Obrázok prílohy",
"notifications_attachment_link_expired": "odkaz na stiahnutie vypršal",
"notifications_attachment_file_image": "súbor s obrázkom",
"notifications_attachment_file_video": "video súbor",
"notifications_attachment_file_audio": "zvukový súbor",
"notifications_attachment_file_app": "Súbor aplikácie pre Android",
"notifications_attachment_file_document": "iný dokument",
"notifications_click_copy_url_title": "Skopírovať URL adresu odkazu do schránky",
"notifications_click_copy_url_button": "Kopírovať odkaz",
"notifications_click_open_button": "Otvoriť odkaz",
"notifications_actions_not_supported": "Akcia nie je podporovaná vo webovej aplikácii",
"notifications_none_for_topic_title": "K tejto téme ste zatiaľ nedostali žiadne upozornenia.",
"notifications_none_for_any_title": "Nedostali ste žiadne upozornenia.",
"notifications_none_for_any_description": "Ak chcete posielať oznámenia do témy, jednoducho zadajte adresu PUT alebo POST na adresu URL témy. Tu je príklad s použitím jednej z vašich tém.",
"notifications_no_subscriptions_title": "Zdá sa, že zatiaľ nemáte žiadne prihlásenia na odber.",
"display_name_dialog_title": "Zmeniť zobrazovaný názov",
"notifications_no_subscriptions_description": "Kliknutím na odkaz \"{{text odkazu}}\" vytvoríte tému alebo sa na ňu prihlásite. Potom môžete posielať správy prostredníctvom PUT alebo POST a budete tu dostávať oznámenia.",
"notifications_example": "Príklad",
"notifications_more_details": "Ďalšie informácie nájdete na <websiteLink>webovej stránke</websiteLink> alebo v <docsLink>dokumentácií</docsLink>.",
"display_name_dialog_placeholder": "Zobrazený názov",
"reserve_dialog_checkbox_label": "Rezervovať tému a nakonfigurovať prístup",
"notifications_loading": "Načítavanie oznámení …",
"publish_dialog_title_no_topic": "Zverejniť oznámenie",
"publish_dialog_title_topic": "Zverejniť v {{topic}}",
"publish_dialog_progress_uploading": "Nahrávanie…",
"publish_dialog_progress_uploading_detail": "Nahrávanie {{loaded}}/{{total}} ({{percent}}%) …",
"publish_dialog_message_published": "Oznámenie zverejnené",
"publish_dialog_attachment_limits_file_and_quota_reached": "prekročí {{fileSizeLimit}} limit súboru a kvótu, {{remainingBytes}} zostáva",
"publish_dialog_attachment_limits_file_reached": "prekračuje {{fileSizeLimit}} limit súboru",
"publish_dialog_attachment_limits_quota_reached": "prekračuje kvótu, {{remainingBytes}} zostáva",
"publish_dialog_emoji_picker_show": "Vyberte emoji",
"publish_dialog_priority_min": "Min. priorita",
"publish_dialog_priority_low": "Nízka priorita",
"publish_dialog_priority_default": "Predvolená priorita",
"publish_dialog_priority_high": "Vysoká priorita",
"publish_dialog_priority_max": "Max. priorita",
"publish_dialog_base_url_label": "URL Adresa služby",
"publish_dialog_base_url_placeholder": "URL adresa služby, napr. https://example.com",
"publish_dialog_topic_label": "Názov témy",
"publish_dialog_topic_placeholder": "Názov témy, napr. phil_alerts",
"publish_dialog_topic_reset": "Resetovať tému",
"publish_dialog_title_label": "Názov",
"publish_dialog_title_placeholder": "Názov oznámenia, napr. Upozornenie na miesto na disku",
"publish_dialog_tags_label": "Štítky",
"publish_dialog_message_label": "Správa",
"publish_dialog_priority_label": "Priorita",
"publish_dialog_click_label": "Kliknite na URL",
"publish_dialog_click_placeholder": "URL adresa sa otvorí po kliknutí na oznámenie",
"publish_dialog_email_label": "Email",
"publish_dialog_email_placeholder": "Emailová adresa, na ktorú sa má oznámenie zaslať, napr. phil@example.com",
"publish_dialog_call_label": "Telefonovať",
"publish_dialog_call_item": "Zavolať na telefónne číslo {{number}}",
"publish_dialog_call_reset": "Odstrániť telefón",
"publish_dialog_attach_label": "URL prílohy",
"publish_dialog_attach_reset": "Odstrániť URL prílohy",
"publish_dialog_filename_label": "Názov súboru",
"publish_dialog_filename_placeholder": "Názov súboru prílohy",
"publish_dialog_delay_label": "Oneskorenie",
"publish_dialog_delay_placeholder": "Oneskorenie doručenia, napr. {{unixTimestamp}}, {{relativeTime}} alebo \"{{naturalLanguage}}\" (len v angličtine)",
"publish_dialog_delay_reset": "Odstrániť oneskorené doručenie",
"publish_dialog_chip_call_label": "Telefonovať",
"publish_dialog_other_features": "Ďalšie funkcie:",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Žiadne overené telefónne čísla",
"publish_dialog_chip_attach_url_label": "Pripojiť súbor pomocou adresy URL",
"publish_dialog_chip_delay_label": "Oneskoriť doručenie",
"publish_dialog_chip_topic_label": "Zmeniť tému",
"publish_dialog_button_cancel_sending": "Zrušiť odosielanie",
"publish_dialog_button_send": "Odoslať",
"publish_dialog_checkbox_publish_another": "Zverejniť ďalšie",
"publish_dialog_attached_file_title": "Priložený súbor:",
"subscribe_dialog_subscribe_button_cancel": "Zrušiť",
"subscribe_dialog_subscribe_title": "Odoberať tému",
"subscribe_dialog_subscribe_base_url_label": "URL Adresa služby",
"subscribe_dialog_subscribe_topic_placeholder": "Názov témy, napr. phil_alerts",
"publish_dialog_attached_file_filename_placeholder": "Názov súboru prílohy",
"publish_dialog_attached_file_remove": "Odstrániť priložený súbor",
"publish_dialog_drop_file_here": "Vložiť súbor",
"subscribe_dialog_login_password_label": "Heslo",
"account_basics_password_dialog_confirm_password_label": "Potvrdenie hesla",
"account_basics_title": "Účet",
"account_delete_dialog_button_cancel": "Zrušiť",
"account_delete_dialog_label": "Heslo",
"prefs_reservations_dialog_title_add": "Rezervovať tému",
"publish_dialog_button_cancel": "Zrušiť",
"account_upgrade_dialog_button_cancel": "Zrušiť",
"account_tokens_dialog_button_cancel": "Zrušiť",
"common_cancel": "Zrušiť",
"common_add": "Pridať",
"account_basics_username_title": "Používateľské meno",
"signup_form_password": "Heslo",
"signup_error_creation_limit_reached": "Dosiahnutý limit na vytvorenie konta",
"account_basics_password_title": "Heslo",
"action_bar_change_display_name": "Zmeniť zobrazovaný názov",
"prefs_users_dialog_password_label": "Heslo",
"action_bar_sign_up": "Zaregistrovať sa",
"login_link_signup": "Zaregistrovať sa",
"signup_already_have_account": "Už máte účet? Prihláste sa!",
"signup_disabled": "Registrácia je vypnutá",
"login_title": "Prihláste sa do svojho konta ntfy",
"action_bar_show_menu": "Zobraziť menu",
"action_bar_reservation_add": "Rezervovať tému",
"action_bar_reservation_delete": "Odstrániť rezerváciu",
"action_bar_reservation_limit_reached": "Dosiahnutý limit",
"action_bar_send_test_notification": "Odoslať testovacie oznámenie",
"action_bar_clear_notifications": "Vymazať všetky oznámenia",
"publish_dialog_message_placeholder": "Sem napíšte správu",
"action_bar_profile_logout": "Odhlásiť sa",
"message_bar_type_message": "Sem napíšte správu",
"message_bar_error_publishing": "Chyba pri zverejňovaní oznámenia",
"nav_button_documentation": "Dokumentácia",
"nav_button_publish_message": "Zverejniť oznámenie",
"nav_button_subscribe": "Odoberať tému",
"nav_button_muted": "Oznámenia stlmené",
"nav_button_connecting": "pripájanie",
"nav_upgrade_banner_description": "Rezervovať témy, viac správ a e-mailov a väčšie prílohy",
"nav_upgrade_banner_label": "Vylepšiť na ntfy Pro",
"alert_grant_title": "Oznámenia sú vypnuté",
"alert_grant_button": "Prideliť teraz",
"alert_not_supported_title": "Oznámenia nie sú podporované",
"alert_not_supported_description": "Oznámenia nie sú vo vašom prehliadači podporované.",
"notifications_attachment_copy_url_title": "Kopírovať URL adresu prílohy do schránky",
"notifications_attachment_copy_url_button": "Kopírovať adresu URL",
"notifications_attachment_open_title": "Prejsť na {{url}}",
"notifications_actions_open_url_title": "Prejsť na {{url}}",
"notifications_attachment_open_button": "Otvoriť prílohu",
"notifications_attachment_link_expires": "platnosť odkazu vyprší {{date}}",
"notifications_none_for_topic_description": "Ak chcete posielať oznámenia do tejto témy, jednoducho zadajte adresu PUT alebo POST na URL adresu témy.",
"notifications_actions_http_request_title": "Odoslať HTTP {{method}} na {{url}}",
"display_name_dialog_description": "Nastavenie alternatívneho názvu témy, ktorá sa zobrazuje v zozname odberov. Pomáha to ľahšie identifikovať témy so zložitými názvami.",
"prefs_users_table_base_url_header": "URL Adresa služby",
"publish_dialog_tags_placeholder": "Zoznam štítkov oddelených čiarkou, napr. varovanie, srv1-backup",
"publish_dialog_chip_click_label": "Kliknite na URL",
"publish_dialog_email_reset": "Odstrániť email na preposielanie",
"publish_dialog_click_reset": "Odobrať URL kliknutím",
"publish_dialog_attach_placeholder": "Pripojiť súbor pomocou URL adresy, napr. https://f-droid.org/F-Droid.apk",
"publish_dialog_chip_email_label": "Preposlanie na email",
"publish_dialog_chip_attach_file_label": "Pripojiť miestny súbor",
"publish_dialog_details_examples_description": "Príklady a podrobný opis všetkých funkcií odosielania nájdete v <docsLink>dokumentácii</docsLink>.",
"account_upgrade_dialog_tier_features_no_calls": "Žiadne telefonáty",
"account_upgrade_dialog_billing_contact_email": "V prípade otázok týkajúcich sa fakturácie nás prosím <Link>kontaktujte tu</Link>.",
"account_tokens_dialog_title_create": "Vytvoriť prístupový token",
"prefs_reservations_dialog_title_edit": "Upraviť rezervovanú tému",
"account_basics_tier_interval_monthly": "mesačne",
"account_basics_tier_canceled_subscription": "Vaše predplatné bolo zrušené a bude preradené na bezplatné konto k dátumu {{date}}.",
"priority_default": "predvolená",
"prefs_notifications_min_priority_title": "Najnižšia priorita",
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} denný telefonát",
"account_upgrade_dialog_tier_current_label": "Aktuálne",
"account_basics_password_dialog_current_password_incorrect": "Nesprávne heslo",
"account_tokens_table_token_header": "Token",
"prefs_notifications_delete_after_never": "Nikdy",
"prefs_users_description": "Tu môžete pridávať/odstraňovať používateľov pre svoje chránené témy. Upozorňujeme, že používateľské meno a heslo sú uložené v lokálnom úložisku prehliadača.",
"account_basics_phone_numbers_dialog_number_label": "Telefónne číslo",
"subscribe_dialog_subscribe_description": "Témy nemusia byť chránené heslom, preto vyberte názov, ktorý nie je ľahké uhádnuť. Po prihlásení sa na odber môžete PUT/POST oznámenia.",
"account_basics_password_dialog_button_submit": "Zmeniť heslo",
"account_basics_phone_numbers_dialog_check_verification_button": "Potvrdiť kód",
"account_upgrade_dialog_interval_yearly_discount_save_up_to": "ušetrite až {{discount}}%",
"account_tokens_dialog_label": "Označenie, napr. Radarr notifications",
"account_tokens_table_expires_header": "Vyprší",
"account_upgrade_dialog_proration_info": "<strong>Vyhlásenie</strong>: Pri prechode medzi platenými plánmi sa rozdiel v cene <strong>účtuje okamžite</strong>. Pri prechode na nižšiu úroveň sa zostatok použije na platbu za budúce fakturačné obdobia.",
"prefs_reservations_dialog_access_label": "Prístup",
"account_usage_attachment_storage_title": "Ukladanie príloh",
"prefs_users_dialog_username_label": "Používateľské meno, napr. phil",
"account_usage_messages_title": "Zverejnené správy",
"emoji_picker_search_clear": "Vymazať vyhľadávanie",
"prefs_reservations_table_not_subscribed": "Odber nie je prihlásený",
"account_upgrade_dialog_tier_features_emails_other": "{{emails}} denné emaily",
"prefs_notifications_min_priority_max_only": "Iba najvyššia priorita",
"account_upgrade_dialog_tier_features_calls_other": "{{calls}} denné telefonáty",
"prefs_notifications_sound_description_some": "Oznámenia pri príchode prehrávajú zvuk {{sound}}",
"prefs_reservations_edit_button": "Upraviť prístup k téme",
"account_basics_phone_numbers_dialog_verify_button_sms": "Poslať SMS",
"account_basics_tier_change_button": "Zmeniť",
"account_tokens_dialog_expires_never": "Platnosť tokenu nikdy nevyprší",
"subscribe_dialog_login_title": "Vyžaduje sa prihlásenie",
"account_tokens_dialog_expires_x_days": "Token vyprší za {{days}} dní",
"prefs_reservations_table_everyone_read_only": "Môžem publikovať a odoberať, každý môže odoberať",
"prefs_reservations_table_everyone_deny_all": "Iba ja môžem publikovať a odoberať",
"account_basics_phone_numbers_dialog_description": "Ak chcete používať funkciu oznamovanie hovorom, musíte pridať a overiť aspoň jedno telefónne číslo. Overenie je možné vykonať prostredníctvom SMS alebo telefonického hovoru.",
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} rezervovaná téma",
"account_delete_title": "Odstrániť účet",
"subscribe_dialog_login_button_login": "Prihlásenie",
"account_upgrade_dialog_tier_features_no_reservations": "Žiadne rezervované témy",
"prefs_users_table_cannot_delete_or_edit": "Nie je možné odstrániť alebo upraviť prihláseného používateľa",
"account_basics_tier_admin_suffix_with_tier": "(s úrovňou {{tier}})",
"prefs_notifications_delete_after_three_hours_description": "Oznámenia sa automaticky odstránia po troch hodinách",
"prefs_notifications_delete_after_three_hours": "Po troch hodinách",
"prefs_notifications_min_priority_description_x_or_higher": "Zobraziť oznámenia, ak je priorita {{number}} ({{name}}) alebo vyššia",
"reservation_delete_dialog_description": "Odstránením rezervácie sa vzdáte vlastníctva témy a umožníte ostatným, aby si ju rezervovali. Existujúce správy a prílohy si môžete ponechať alebo odstrániť.",
"subscribe_dialog_login_username_label": "Používateľské meno, napr. phil",
"subscribe_dialog_error_user_not_authorized": "Používateľ {{username}} nie je autorizovaný",
"prefs_reservations_table_everyone_read_write": "Každý môže publikovať a odoberať",
"prefs_reservations_dialog_title_delete": "Odstrániť rezervovanú tému",
"prefs_users_table": "Tabuľka používateľov",
"prefs_reservations_table_topic_header": "Téma",
"reservation_delete_dialog_submit_button": "Vymazať rezerváciu",
"prefs_reservations_limit_reached": "Dosiahli ste limit rezervovaných tém.",
"account_upgrade_dialog_interval_monthly": "Mesačne",
"prefs_users_add_button": "Pridať používateľa",
"account_upgrade_dialog_tier_features_messages_other": "{{messages}} denné správy",
"account_basics_phone_numbers_no_phone_numbers_yet": "Zatiaľ žiadne telefónne čísla",
"subscribe_dialog_subscribe_button_generate_topic_name": "Vygenerovať názov",
"prefs_appearance_language_title": "Jazyk",
"prefs_notifications_delete_after_one_day_description": "Oznámenia sa automaticky odstránia po jednom dni",
"subscribe_dialog_subscribe_button_subscribe": "Odoberať",
"account_tokens_table_never_expires": "Nikdy nevyprší",
"account_tokens_delete_dialog_title": "Odstrániť prístupový token",
"prefs_notifications_delete_after_one_month": "Po jednom mesiaci",
"account_basics_phone_numbers_dialog_title": "Pridať telefónne číslo",
"account_tokens_delete_dialog_description": "Pred odstránením prístupového tokenu sa uistite, že ho aktívne nepoužívajú žiadne aplikácie ani skripty. <strong>Túto akciu nie je možné vrátiť späť</strong>.",
"account_tokens_table_label_header": "Označenie",
"account_upgrade_dialog_billing_contact_website": "Otázky týkajúce sa fakturácie nájdete na našej <Link>webovej stránke</Link>.",
"account_basics_username_admin_tooltip": "Ste Admin",
"prefs_notifications_delete_after_never_description": "Oznámenia sa nikdy automaticky neodstránia",
"account_delete_dialog_description": "Tým sa vaše konto natrvalo odstráni vrátane všetkých údajov uložených na serveri. Po vymazaní bude vaše používateľské meno 7 dní nedostupné. Ak naozaj chcete pokračovať, potvrďte svoje heslo v poli nižšie.",
"account_upgrade_dialog_tier_features_reservations_other": "{{reservations}} rezervované témy",
"account_usage_reservations_none": "Žiadne rezervované témy pre toto konto",
"prefs_notifications_sound_description_none": "Pri príchode oznámení sa neprehráva žiadny zvuk",
"account_tokens_description": "Pri publikovaní a prihlasovaní prostredníctvom rozhrania ntfy API používajte prístupové tokeny, aby ste nemuseli posielať prihlasovacie údaje k účtu. Viacej informácií nájdete v <Link>dokumentácií</Link>.",
"prefs_reservations_table": "Tabuľka rezervovaných tém",
"emoji_picker_search_placeholder": "Vyhľadať emoji",
"account_upgrade_dialog_button_cancel_subscription": "Zrušiť predplatné",
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} denný email",
"account_upgrade_dialog_tier_features_attachment_file_size": "{{filesize}} na jeden súbor",
"prefs_reservations_description": "Tu si môžete rezervovať názvy tém na osobné použitie. Rezervovaním témy získate vlastníctvo nad témou a môžete definovať prístupové práva pre ostatných používateľov k téme.",
"account_usage_title": "Používanie",
"account_basics_tier_upgrade_button": "Vylepšiť na PRO verziu",
"prefs_users_description_no_sync": "Používatelia a heslá nie sú synchronizované s vaším účtom.",
"account_tokens_dialog_title_edit": "Upraviť prístupový token",
"account_upgrade_dialog_tier_features_messages_one": "{{messages}} denná správa",
"account_upgrade_dialog_reservations_warning_one": "Vybraná úroveň umožňuje menej rezervovaných tém ako vaša aktuálna úroveň. Pred zmenou úrovne <strong>vymažte aspoň jednu rezerváciu</strong>. Rezervácie môžete odstrániť v <Link>Nastaveniach</Link>.",
"subscribe_dialog_error_topic_already_reserved": "Téma je už rezervovaná",
"prefs_users_table_user_header": "Používateľ",
"error_boundary_stack_trace": "Výpis zásobníka",
"prefs_notifications_delete_after_one_week": "Po jednom týždni",
"prefs_reservations_delete_button": "Resetovať prístup k téme",
"account_basics_tier_admin_suffix_no_tier": "(bez úrovne)",
"prefs_notifications_delete_after_one_week_description": "Oznámenia sa automaticky odstránia po jednom týždni",
"error_boundary_unsupported_indexeddb_description": "Webová aplikácia ntfy potrebuje na fungovanie IndexedDB a váš prehliadač nepodporuje IndexedDB v režime súkromného prehliadania.<br/><br/>Je to síce nešťastné, ale aj tak nemá veľký zmysel používať webovú aplikáciu ntfy v režime súkromného prehliadania, pretože všetko je uložené v úložisku prehliadača. Viac informácií si môžete prečítať <githubLink>v tomto probléme GitHubu</githubLink> alebo sa s nami porozprávať na <discordLink>Discord</discordLink> alebo <matrixLink>Matrix</matrixLink>.",
"account_basics_tier_payment_overdue": "Vaša platba je po termíne splatnosti. Aktualizujte prosím svoj spôsob platby, inak bude váš účet preradený do nižšej kategórie.",
"account_basics_tier_description": "Úroveň výkonu vášho účtu",
"account_basics_phone_numbers_description": "Pre oznamovanie hovorom",
"account_basics_tier_free": "Zadarmo",
"account_upgrade_dialog_cancel_warning": "Týmto <strong>zrušíte svoje predplatné</strong> a {{date}} prejdete na nižšiu úroveň svojho účtu. V tento deň <strong>budú odstránené</strong> rezervácie tém, ako aj správy uložené vo vyrovnávacej pamäti servera.",
"account_basics_tier_admin": "Admin",
"prefs_notifications_sound_title": "Zvuk oznámenia",
"prefs_notifications_min_priority_default_and_higher": "Predvolená priorita a vyššia",
"prefs_reservations_table_access_header": "Prístup",
"account_tokens_table_copied_to_clipboard": "Prístupový token skopírovaný",
"account_tokens_dialog_expires_x_hours": "Token vyprší za {{hours}} hodín",
"prefs_users_edit_button": "Upraviť používateľa",
"account_upgrade_dialog_title": "Zmeniť úroveň účtu",
"priority_low": "nízka",
"prefs_reservations_table_click_to_subscribe": "Kliknutím sa prihlásite na odber",
"account_basics_password_description": "Zmeniť heslo účtu",
"account_usage_calls_title": "Uskutočnené telefonické hovory",
"error_boundary_description": "Toto samozrejme nemalo nastať. Je mi to veľmi ľúto.<br/>Ak máte chvíľu, <githubLink>nahláste to na GitHub</githubLink> alebo nám dajte vedieť cez <discordLink>Discord</discordLink> alebo <matrixLink>Matrix</matrixLink>.",
"priority_min": "najnižšia",
"account_basics_tier_basic": "Základný",
"prefs_notifications_min_priority_description_any": "Zobraziť všetky oznámenia bez ohľadu na prioritu",
"error_boundary_gathering_info": "Získajte viac informácií…",
"error_boundary_unsupported_indexeddb_title": "Súkromné prehliadanie nie je podporované",
"prefs_notifications_delete_after_one_day": "Po jednom dni",
"error_boundary_title": "Ale nie, ntfy prestalo fungovať",
"reservation_delete_dialog_action_keep_description": "Správy a prílohy, ktoré sú uložené v medzipamäti na serveri, budú verejne viditeľné pre ľudí, ktorí poznajú názov témy.",
"prefs_reservations_add_button": "Pridať rezervovanú tému",
"prefs_reservations_title": "Rezervované témy",
"account_basics_phone_numbers_copied_to_clipboard": "Telefónne číslo skopírované do schránky",
"prefs_reservations_dialog_description": "Rezervovaním témy získate vlastníctvo nad témou a môžete definovať prístupové práva pre ostatných používateľov k téme.",
"account_basics_tier_title": "Typ účtu",
"account_usage_cannot_create_portal_session": "Nemožnosť otvoriť fakturačný portál",
"account_tokens_delete_dialog_submit_button": "Trvalo odstrániť token",
"account_delete_description": "Natrvalo odstrániť vaše konto",
"account_basics_phone_numbers_dialog_number_placeholder": "napr. +1222333444",
"account_basics_phone_numbers_dialog_code_placeholder": "napr. 123456",
"prefs_notifications_title": "Oznámenia",
"account_basics_tier_manage_billing_button": "Spravovať fakturáciu",
"account_tokens_title": "Prístupové tokeny",
"account_basics_username_description": "Hej, to si ty ❤",
"prefs_reservations_dialog_topic_label": "Téma",
"prefs_users_title": "Správa používateľov",
"account_basics_tier_interval_yearly": "ročne",
"account_upgrade_dialog_tier_price_billed_monthly": "{{price}} za rok. Účtuje sa mesačne.",
"account_delete_dialog_button_submit": "Natrvalo odstrániť konto",
"account_basics_phone_numbers_dialog_channel_call": "Hovor",
"account_basics_password_dialog_new_password_label": "Nové heslo",
"account_tokens_dialog_expires_unchanged": "Ponechať dátum skončenia platnosti nezmenený",
"error_boundary_button_copy_stack_trace": "Kopírovať výpis zásobníka",
"account_tokens_dialog_title_delete": "Odstrániť prístupový token",
"account_usage_of_limit": "z {{limit}}",
"reservation_delete_dialog_action_keep_title": "Ponechať správy a prílohy uložené v medzipamäti",
"prefs_notifications_sound_no_sound": "Bez zvuku",
"account_upgrade_dialog_interval_yearly": "Ročne",
"account_upgrade_dialog_button_redirect_signup": "Zaregistrujte sa teraz",
"subscribe_dialog_error_user_anonymous": "anonymný",
"account_upgrade_dialog_tier_price_billed_yearly": "{{price}} účtovaná ročne. Uložiť {{save}}.",
"prefs_notifications_min_priority_high_and_higher": "Vysoká priorita a vyššia",
"account_usage_basis_ip_description": "Štatistiky a limity používania tohto účtu sú založené na vašej IP adrese, takže môžu byť zdieľané s ostatnými používateľmi. Vyššie uvedené limity sú približné hodnoty založené na existujúcich rýchlostných limitoch.",
"account_basics_password_dialog_title": "Zmeniť heslo",
"priority_max": "najvyššia",
"account_usage_limits_reset_daily": "Limity používania sa obnovujú denne o polnoci (UTC)",
"account_usage_unlimited": "Nekonečné",
"prefs_users_delete_button": "Odstrániť používateľa",
"prefs_notifications_min_priority_any": "Akákoľvek priorita",
"account_tokens_dialog_expires_label": "Platnosť prístupového tokenu vyprší za",
"account_basics_phone_numbers_title": "Telefónne čísla",
"prefs_notifications_delete_after_title": "Odstrániť oznámenia",
"account_upgrade_dialog_interval_yearly_discount_save": "ušetríte {{discount}}%",
"prefs_users_dialog_title_edit": "Upraviť používateľa",
"account_basics_password_dialog_current_password_label": "Aktuálne heslo",
"prefs_notifications_min_priority_low_and_higher": "Nízka priorita a vyššia",
"account_tokens_dialog_button_update": "Aktualizovať token",
"account_upgrade_dialog_tier_features_attachment_total_size": "{{totalsize}} celkový úložný priestor",
"prefs_reservations_table_everyone_write_only": "Môžem publikovať a odoberať, každý môže publikovať",
"prefs_appearance_title": "Vzhlad",
"account_tokens_table_cannot_delete_or_edit": "Nie je možné upraviť alebo odstrániť aktuálny token relácie",
"prefs_notifications_sound_play": "Prehrať vybraný zvuk",
"account_tokens_table_last_access_header": "Posledný prístup",
"account_tokens_table_last_origin_tooltip": "Z IP adresy {{ip}}, kliknite na vyhľadávanie",
"account_usage_reservations_title": "Rezervované témy",
"account_upgrade_dialog_tier_price_per_month": "mesiac",
"account_usage_calls_none": "S týmto účtom nie je možné uskutočňovať žiadne telefonické hovory",
"account_tokens_table_current_session": "Aktuálna relácia prehliadača",
"account_upgrade_dialog_button_pay_now": "Zaplatiť a predplatiť si",
"subscribe_dialog_subscribe_use_another_label": "Použiť iný server",
"reservation_delete_dialog_action_delete_title": "Odstrániť správy a prílohy uložené v medzipamäti",
"account_basics_phone_numbers_dialog_code_label": "Overovací kód",
"reservation_delete_dialog_action_delete_description": "Správy a prílohy uložené v medzipamäti sa natrvalo vymažú. Túto akciu nemožno vrátiť späť.",
"account_basics_tier_paid_until": "Predplatné zaplatené do {{date}} s automatickou obnovou",
"account_usage_attachment_storage_description": "{{filesize}} na súbor, vymazaný po {{expiry}}",
"prefs_notifications_delete_after_one_month_description": "Oznámenia sa automaticky odstránia po jednom mesiaci",
"account_basics_phone_numbers_dialog_verify_button_call": "Zavolajte mi",
"prefs_users_dialog_base_url_label": "URL adresa služby, napr. https://ntfy.sh",
"account_usage_emails_title": "Odoslané emaily",
"account_basics_phone_numbers_dialog_channel_sms": "SMS",
"account_upgrade_dialog_tier_selected_label": "Vybrané",
"account_upgrade_dialog_button_update_subscription": "Aktualizovať predplatné",
"priority_high": "vysoká",
"account_delete_dialog_billing_warning": "Odstránením konta sa okamžite zruší aj vaše fakturačné predplatné. Už nebudete mať prístup k fakturačnému panelu.",
"prefs_notifications_min_priority_description_max": "Zobraziť oznámenia, ak je priorita 5 (max)",
"subscribe_dialog_login_description": "Táto téma je chránená heslom. Ak sa chcete prihlásiť na odber témy, zadajte používateľské meno a heslo.",
"account_upgrade_dialog_reservations_warning_other": "Vybraná úroveň umožňuje menej rezervovaných tém ako vaša aktuálna úroveň. Pred zmenou úrovne <strong>vymažte aspoň {{count}} rezervácií</strong>. Rezervácie môžete odstrániť v <Link>Nastaveniach</Link>.",
"prefs_users_dialog_title_add": "Pridať používateľa",
"account_tokens_dialog_button_create": "Vytvoriť token",
"account_tokens_table_create_token_button": "Vytvoriť prístupový token"
}

View file

@ -77,7 +77,7 @@
"notifications_example": "Örnek", "notifications_example": "Örnek",
"notifications_more_details": "Daha fazla bilgi için <websiteLink>web sitesine</websiteLink> veya <docsLink>belgelendirmeye</docsLink> bakın.", "notifications_more_details": "Daha fazla bilgi için <websiteLink>web sitesine</websiteLink> veya <docsLink>belgelendirmeye</docsLink> bakın.",
"publish_dialog_chip_attach_url_label": "URL ile dosya ekle", "publish_dialog_chip_attach_url_label": "URL ile dosya ekle",
"prefs_notifications_min_priority_default_and_higher": "Varsayılan öncelik ve üstü", "prefs_notifications_min_priority_default_and_higher": "Öntanımlı öncelik ve üstü",
"prefs_notifications_delete_after_three_hours": "Üç saat sonra", "prefs_notifications_delete_after_three_hours": "Üç saat sonra",
"notifications_none_for_any_description": "Bir konuya bildirim göndermek için konu URL'sine PUT veya POST göndermeniz yeterlidir. İşte konularınızdan birini kullanan bir örnek.", "notifications_none_for_any_description": "Bir konuya bildirim göndermek için konu URL'sine PUT veya POST göndermeniz yeterlidir. İşte konularınızdan birini kullanan bir örnek.",
"notifications_no_subscriptions_title": "Henüz aboneliğiniz yok gibi görünüyor.", "notifications_no_subscriptions_title": "Henüz aboneliğiniz yok gibi görünüyor.",

Some files were not shown because too many files have changed in this diff Show more