repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
7f7174f
parent
e04a2e1
author
Antonio Mika
date
2024-11-07 19:45:36 +0000 UTC
Allow unauthenticated access to public pipes (#157)


Co-authored-by: Eric Bower <me@erock.io>
6 files changed,  +280, -183
M go.mod
M go.sum
M db/db.go
+1, -0
1@@ -325,6 +325,7 @@ var DenyList = []string{
2 	"new",
3 	"create",
4 	"www",
5+	"public",
6 }
7 
8 type DB interface {
M go.mod
+45, -46
  1@@ -19,33 +19,33 @@ require (
  2 	github.com/alecthomas/chroma/v2 v2.14.0
  3 	github.com/antoniomika/syncmap v1.0.0
  4 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
  5-	github.com/charmbracelet/bubbles v0.18.0
  6-	github.com/charmbracelet/bubbletea v1.1.1
  7-	github.com/charmbracelet/glamour v0.7.0
  8-	github.com/charmbracelet/lipgloss v0.13.0
  9+	github.com/charmbracelet/bubbles v0.20.0
 10+	github.com/charmbracelet/bubbletea v1.1.2
 11+	github.com/charmbracelet/glamour v0.8.0
 12+	github.com/charmbracelet/lipgloss v1.0.0
 13 	github.com/charmbracelet/promwish v0.7.0
 14 	github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa
 15 	github.com/charmbracelet/wish v1.4.3
 16 	github.com/google/go-cmp v0.6.0
 17 	github.com/google/uuid v1.6.0
 18-	github.com/gorilla/feeds v1.1.2
 19+	github.com/gorilla/feeds v1.2.0
 20 	github.com/lib/pq v1.10.9
 21-	github.com/microcosm-cc/bluemonday v1.0.26
 22-	github.com/minio/minio-go/v7 v7.0.77
 23+	github.com/microcosm-cc/bluemonday v1.0.27
 24+	github.com/minio/minio-go/v7 v7.0.80
 25 	github.com/mmcdole/gofeed v1.3.0
 26 	github.com/muesli/reflow v0.3.0
 27 	github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257
 28 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
 29 	github.com/picosh/pobj v0.0.0-20241016194248-c39198b2ff23
 30-	github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed
 31-	github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848
 32-	github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e
 33+	github.com/picosh/pubsub v0.0.0-20241030185810-e24d08b67ab8
 34+	github.com/picosh/send v0.0.0-20241107150437-0febb0049b4f
 35+	github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9
 36 	github.com/picosh/utils v0.0.0-20241018143404-b351d5d765f3
 37 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
 38-	github.com/sendgrid/sendgrid-go v3.14.0+incompatible
 39+	github.com/sendgrid/sendgrid-go v3.16.0+incompatible
 40 	github.com/simplesurance/go-ip-anonymizer v0.0.0-20200429124537-35a880f8e87d
 41-	github.com/x-way/crawlerdetect v0.2.21
 42-	github.com/yuin/goldmark v1.7.1
 43+	github.com/x-way/crawlerdetect v0.2.24
 44+	github.com/yuin/goldmark v1.7.8
 45 	github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
 46 	github.com/yuin/goldmark-meta v1.1.0
 47 	go.abhg.dev/goldmark/anchor v0.1.1
 48@@ -57,29 +57,29 @@ require (
 49 
 50 require (
 51 	git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082 // indirect
 52-	github.com/DavidGamba/go-getoptions v0.30.0 // indirect
 53-	github.com/PuerkitoBio/goquery v1.9.2 // indirect
 54+	github.com/DavidGamba/go-getoptions v0.31.0 // indirect
 55+	github.com/PuerkitoBio/goquery v1.10.0 // indirect
 56 	github.com/andybalholm/cascadia v1.3.2 // indirect
 57 	github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
 58 	github.com/atotto/clipboard v0.1.4 // indirect
 59-	github.com/aws/aws-sdk-go-v2 v1.32.1 // indirect
 60+	github.com/aws/aws-sdk-go-v2 v1.32.3 // indirect
 61 	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
 62-	github.com/aws/aws-sdk-go-v2/config v1.27.42 // indirect
 63-	github.com/aws/aws-sdk-go-v2/credentials v1.17.40 // indirect
 64-	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16 // indirect
 65-	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29 // indirect
 66-	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20 // indirect
 67-	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20 // indirect
 68+	github.com/aws/aws-sdk-go-v2/config v1.28.1 // indirect
 69+	github.com/aws/aws-sdk-go-v2/credentials v1.17.42 // indirect
 70+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 // indirect
 71+	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.35 // indirect
 72+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect
 73+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect
 74 	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
 75-	github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20 // indirect
 76+	github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect
 77 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
 78-	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1 // indirect
 79-	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1 // indirect
 80-	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1 // indirect
 81-	github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1 // indirect
 82-	github.com/aws/aws-sdk-go-v2/service/sso v1.24.1 // indirect
 83-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1 // indirect
 84-	github.com/aws/aws-sdk-go-v2/service/sts v1.32.1 // indirect
 85+	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 // indirect
 86+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect
 87+	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 // indirect
 88+	github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 // indirect
 89+	github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 // indirect
 90+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 // indirect
 91+	github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 // indirect
 92 	github.com/aws/smithy-go v1.22.0 // indirect
 93 	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
 94 	github.com/aymerick/douceur v0.2.0 // indirect
 95@@ -87,16 +87,16 @@ require (
 96 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 97 	github.com/charmbracelet/keygen v0.5.1 // indirect
 98 	github.com/charmbracelet/log v0.4.0 // indirect
 99-	github.com/charmbracelet/x/ansi v0.3.2 // indirect
100+	github.com/charmbracelet/x/ansi v0.4.2 // indirect
101 	github.com/charmbracelet/x/conpty v0.1.0 // indirect
102-	github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3 // indirect
103+	github.com/charmbracelet/x/errors v0.0.0-20241101155414-3df16cb7eefd // indirect
104 	github.com/charmbracelet/x/input v0.2.0 // indirect
105 	github.com/charmbracelet/x/term v0.2.0 // indirect
106 	github.com/charmbracelet/x/termios v0.1.0 // indirect
107-	github.com/creack/pty v1.1.23 // indirect
108+	github.com/creack/pty v1.1.24 // indirect
109 	github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878 // indirect
110-	github.com/delthas/go-localeinfo v0.0.0-20221116001557-686a1e185118 // indirect
111-	github.com/dlclark/regexp2 v1.11.0 // indirect
112+	github.com/delthas/go-localeinfo v0.0.0-20240813094314-e5413e186769 // indirect
113+	github.com/dlclark/regexp2 v1.11.4 // indirect
114 	github.com/dsoprea/go-exif v0.0.0-20230826092837-6579e82b732d // indirect
115 	github.com/dsoprea/go-exif/v2 v2.0.0-20230826092837-6579e82b732d // indirect
116 	github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 // indirect
117@@ -122,7 +122,7 @@ require (
118 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
119 	github.com/gorilla/css v1.0.1 // indirect
120 	github.com/json-iterator/go v1.1.12 // indirect
121-	github.com/klauspost/compress v1.17.10 // indirect
122+	github.com/klauspost/compress v1.17.11 // indirect
123 	github.com/klauspost/cpuid/v2 v2.2.8 // indirect
124 	github.com/kr/fs v0.1.0 // indirect
125 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
126@@ -131,7 +131,7 @@ require (
127 	github.com/mattn/go-localereader v0.0.1 // indirect
128 	github.com/mattn/go-runewidth v0.0.16 // indirect
129 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
130-	github.com/minio/madmin-go/v3 v3.0.70 // indirect
131+	github.com/minio/madmin-go/v3 v3.0.75 // indirect
132 	github.com/minio/md5-simd v1.1.2 // indirect
133 	github.com/mmcdole/goxpp v1.1.1 // indirect
134 	github.com/mmcloughlin/md4 v0.1.2 // indirect
135@@ -141,17 +141,16 @@ require (
136 	github.com/muesli/cancelreader v0.2.2 // indirect
137 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
138 	github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e // indirect
139-	github.com/olekukonko/tablewriter v0.0.5 // indirect
140 	github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
141 	github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc // indirect
142-	github.com/pkg/sftp v1.13.6 // indirect
143+	github.com/pkg/sftp v1.13.7 // indirect
144 	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
145-	github.com/prometheus/client_golang v1.20.4 // indirect
146+	github.com/prometheus/client_golang v1.20.5 // indirect
147 	github.com/prometheus/client_model v0.6.1 // indirect
148-	github.com/prometheus/common v0.60.0 // indirect
149+	github.com/prometheus/common v0.60.1 // indirect
150 	github.com/prometheus/procfs v0.15.1 // indirect
151 	github.com/prometheus/prom2json v1.4.1 // indirect
152-	github.com/prometheus/prometheus v0.54.1 // indirect
153+	github.com/prometheus/prometheus v0.55.0 // indirect
154 	github.com/rivo/uniseg v0.4.7 // indirect
155 	github.com/rogpeppe/go-internal v1.11.0 // indirect
156 	github.com/rs/xid v1.6.0 // indirect
157@@ -160,19 +159,19 @@ require (
158 	github.com/sendgrid/rest v2.6.9+incompatible // indirect
159 	github.com/shirou/gopsutil/v3 v3.24.5 // indirect
160 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
161-	github.com/tinylib/msgp v1.2.2 // indirect
162+	github.com/tinylib/msgp v1.2.4 // indirect
163 	github.com/tklauser/go-sysconf v0.3.14 // indirect
164 	github.com/tklauser/numcpus v0.9.0 // indirect
165 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
166-	github.com/yuin/goldmark-emoji v1.0.2 // indirect
167+	github.com/yuin/goldmark-emoji v1.0.4 // indirect
168 	github.com/yusufpapurcu/wmi v1.2.4 // indirect
169-	golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect
170+	golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
171 	golang.org/x/net v0.30.0 // indirect
172 	golang.org/x/sync v0.8.0 // indirect
173 	golang.org/x/sys v0.26.0 // indirect
174 	golang.org/x/term v0.25.0 // indirect
175 	golang.org/x/text v0.19.0 // indirect
176-	golang.org/x/time v0.6.0 // indirect
177+	golang.org/x/time v0.7.0 // indirect
178 	google.golang.org/protobuf v1.35.1 // indirect
179 	mvdan.cc/xurls/v2 v2.5.0 // indirect
180 )
M go.sum
+97, -96
  1@@ -1,10 +1,10 @@
  2 git.sr.ht/~emersion/go-scfg v0.0.0-20231004133111-9dce55c8d63b/go.mod h1:ybgvEJTIx5XbaspSviB3KNa6OdPmAZqDoSud7z8fFlw=
  3 git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082 h1:9Udx5fm4vRtmgDIBjy2ef5QioHbzpw5oHabbhpAUyEw=
  4 git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082/go.mod h1:ybgvEJTIx5XbaspSviB3KNa6OdPmAZqDoSud7z8fFlw=
  5-github.com/DavidGamba/go-getoptions v0.30.0 h1:8x69Fc8k/mEWVE0GknpwQ3uGj56MXOUp17egPxCEAG4=
  6-github.com/DavidGamba/go-getoptions v0.30.0/go.mod h1:zE97E3PR9P3BI/HKyNYgdMlYxodcuiC6W68KIgeYT84=
  7-github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
  8-github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
  9+github.com/DavidGamba/go-getoptions v0.31.0 h1:RvVrggcstVLZiT6BEHlHcXhPXFSCL2fwhxXz4j4xOjo=
 10+github.com/DavidGamba/go-getoptions v0.31.0/go.mod h1:zE97E3PR9P3BI/HKyNYgdMlYxodcuiC6W68KIgeYT84=
 11+github.com/PuerkitoBio/goquery v1.10.0 h1:6fiXdLuUvYs2OJSvNRqlNPoBm6YABE226xrbavY5Wv4=
 12+github.com/PuerkitoBio/goquery v1.10.0/go.mod h1:TjZZl68Q3eGHNBA8CWaxAN7rOU1EbDz3CWuolcO5Yu4=
 13 github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
 14 github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
 15 github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
 16@@ -23,62 +23,64 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP
 17 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
 18 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
 19 github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
 20-github.com/aws/aws-sdk-go-v2 v1.32.1 h1:8WuZ43ytA+TV6QEPT/R23mr7pWyI7bSSiEHdt9BS2Pw=
 21-github.com/aws/aws-sdk-go-v2 v1.32.1/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
 22+github.com/aws/aws-sdk-go-v2 v1.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk=
 23+github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
 24 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0=
 25 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA=
 26-github.com/aws/aws-sdk-go-v2/config v1.27.42 h1:Zsy9coUPuOsCWkjTvHpl2/DB9bptXtv7WeNPxvFr87s=
 27-github.com/aws/aws-sdk-go-v2/config v1.27.42/go.mod h1:FGASs+PuJM2EY+8rt8qyQKLPbbX/S5oY+6WzJ/KE7ko=
 28-github.com/aws/aws-sdk-go-v2/credentials v1.17.40 h1:RjnlA7t0p/IamxAM7FUJ5uS13Vszh4sjVGvsx91tGro=
 29-github.com/aws/aws-sdk-go-v2/credentials v1.17.40/go.mod h1:dgpdnSs1Bp/atS6vLlW83h9xZPP+uSPB/27dFSgC1BM=
 30-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16 h1:fwrer1pJeaiia0CcOfWVbZxvj9Adc7rsuaMTwPR0DIA=
 31-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.16/go.mod h1:XyEwwp8XI4zMar7MTnJ0Sk7qY/9aN8Hp929XhuX5SF8=
 32-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29 h1:eyeHfJ9FAb7sd5ODTkjrfot3gS0Ln4vn/18l7zZMCik=
 33-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.29/go.mod h1:JpzRPe12SjlOmuqgi+/5RmgfbsWzDYdfxe3Abrk2kW8=
 34-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20 h1:OErdlGnt+hg3tTwGYAlKvFkKVUo/TXkoHcxDxuhYYU8=
 35-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.20/go.mod h1:HsPfuL5gs+407ByRXBMgpYoyrV1sgMrzd18yMXQHJpo=
 36-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20 h1:822cE1CYSwY/EZnErlF46pyynuxvf1p+VydHRQW+XNs=
 37-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.20/go.mod h1:79/Tn7H7hYC5Gjz6fbnOV4OeBpkao7E8Tv95RO72pMM=
 38+github.com/aws/aws-sdk-go-v2/config v1.28.1 h1:oxIvOUXy8x0U3fR//0eq+RdCKimWI900+SV+10xsCBw=
 39+github.com/aws/aws-sdk-go-v2/config v1.28.1/go.mod h1:bRQcttQJiARbd5JZxw6wG0yIK3eLeSCPdg6uqmmlIiI=
 40+github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM=
 41+github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M=
 42+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 h1:68jFVtt3NulEzojFesM/WVarlFpCaXLKaBxDpzkQ9OQ=
 43+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18/go.mod h1:Fjnn5jQVIo6VyedMc0/EhPpfNlPl7dHV916O6B+49aE=
 44+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.35 h1:ihPPdcCVSN0IvBByXwqVp28/l4VosBZ6sDulcvU2J7w=
 45+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.35/go.mod h1:JkgEhs3SVF51Dj3m1Bj+yL8IznpxzkwlA3jLg3x7Kls=
 46+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM=
 47+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY=
 48+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6XamDzF/o7ouUGxFzr+nVSIhrs=
 49+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ=
 50 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
 51 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
 52-github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20 h1:HO5UCCkLmeWkJZHLvLDfylKv8ca28XLAX3HojZz2shI=
 53-github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.20/go.mod h1:IO0HUM6Ouk/s7Rx3hiLtFU3mc+9OJFFygjsaxFBhAbk=
 54+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs=
 55+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw=
 56 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
 57 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
 58-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1 h1:UeW3Ul28hkKvB3beWImBvO7U62tSmapxaqk8sX9SMCU=
 59-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.1/go.mod h1:TER/1DuTxSN6RFQpk3xfD9hK4A1gQ7ainfkwHV3LPtU=
 60-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1 h1:5vBMBTakOvtd8aNaicswcrr9qqCYUlasuzyoU6/0g8I=
 61-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.1/go.mod h1:WSUbDa5qdg05Q558KXx2Scb+EDvOPXT9gfET0fyrJSk=
 62-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1 h1:T6oOYbNQ+iqdtG1/mTJvMBg/YFyHR8Z8URyG3qK+Anc=
 63-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.1/go.mod h1:25CEM6c1e2vyLcr3fPritPsdsoMwNAOc9//M1QAwtDk=
 64-github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1 h1:HQR79P0F0C2YQOaS2Z+90YK9DH22z9D6Neplaj0yuy4=
 65-github.com/aws/aws-sdk-go-v2/service/s3 v1.65.1/go.mod h1:xYVl5BX9Ws7+ZM58b3w0kq36TR1Dgw2OMkjSr6YTWXg=
 66-github.com/aws/aws-sdk-go-v2/service/sso v1.24.1 h1:aAIr0WhAgvKrxZtkBqne87Gjmd7/lJVTFkR2l2yuhL8=
 67-github.com/aws/aws-sdk-go-v2/service/sso v1.24.1/go.mod h1:8XhxGMWUfikJuginPQl5SGZ0LSJuNX3TCEQmFWZwHTM=
 68-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1 h1:J6kIsIkgFOaU6aKjigXJoue1XEHtKIIrpSh4vKdmRTs=
 69-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.1/go.mod h1:2V2JLP7tXOmUbL3Hd1ojq+774t2KUAEQ35//shoNEL0=
 70-github.com/aws/aws-sdk-go-v2/service/sts v1.32.1 h1:q76Ig4OaJzVJGNUSGO3wjSTBS94g+EhHIbpY9rPvkxs=
 71-github.com/aws/aws-sdk-go-v2/service/sts v1.32.1/go.mod h1:664dajZ7uS7JMUMUG0R5bWbtN97KECNCVdFDdQ6Ipu8=
 72+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 h1:kT6BcZsmMtNkP/iYMcRG+mIEA/IbeiUimXtGmqF39y0=
 73+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3/go.mod h1:Z8uGua2k4PPaGOYn66pK02rhMrot3Xk3tpBuUFPomZU=
 74+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY=
 75+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4=
 76+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 h1:ZC7Y/XgKUxwqcdhO5LE8P6oGP1eh6xlQReWNKfhvJno=
 77+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3/go.mod h1:WqfO7M9l9yUAw0HcHaikwRd/H6gzYdz7vjejCA5e2oY=
 78+github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 h1:p9TNFL8bFUMd+38YIpTAXpoxyz0MxC7FlbFEH4P4E1U=
 79+github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2/go.mod h1:fNjyo0Coen9QTwQLWeV6WO2Nytwiu+cCcWaTdKCAqqE=
 80+github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 h1:UTpsIf0loCIWEbrqdLb+0RxnTXfWh2vhw4nQmFi4nPc=
 81+github.com/aws/aws-sdk-go-v2/service/sso v1.24.3/go.mod h1:FZ9j3PFHHAR+w0BSEjK955w5YD2UwB/l/H0yAK3MJvI=
 82+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 h1:2YCmIXv3tmiItw0LlYf6v7gEHebLY45kBEnPezbUKyU=
 83+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3/go.mod h1:u19stRyNPxGhj6dRm+Cdgu6N75qnbW7+QN0q0dsAk58=
 84+github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 h1:wVnQ6tigGsRqSWDEEyH6lSAJ9OyFUsSnbaUWChuSGzs=
 85+github.com/aws/aws-sdk-go-v2/service/sts v1.32.3/go.mod h1:VZa9yTFyj4o10YGsmDO4gbQJUvvhY72fhumT8W4LqsE=
 86 github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
 87 github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
 88 github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
 89 github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
 90+github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
 91+github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
 92 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
 93 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 94 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 95 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 96 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 97 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 98-github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
 99-github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
100-github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
101-github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
102-github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng=
103-github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps=
104+github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
105+github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
106+github.com/charmbracelet/bubbletea v1.1.2 h1:naQXF2laRxyLyil/i7fxdpiz1/k06IKquhm4vBfHsIc=
107+github.com/charmbracelet/bubbletea v1.1.2/go.mod h1:9HIU/hBV24qKjlehyj8z1r/tR9TYTQEag+cWZnuXo8E=
108+github.com/charmbracelet/glamour v0.8.0 h1:tPrjL3aRcQbn++7t18wOpgLyl8wrOHUEDS7IZ68QtZs=
109+github.com/charmbracelet/glamour v0.8.0/go.mod h1:ViRgmKkf3u5S7uakt2czJ272WSg2ZenlYEZXT2x7Bjw=
110 github.com/charmbracelet/keygen v0.5.1 h1:zBkkYPtmKDVTw+cwUyY6ZwGDhRxXkEp0Oxs9sqMLqxI=
111 github.com/charmbracelet/keygen v0.5.1/go.mod h1:zznJVmK/GWB6dAtjluqn2qsttiCBhA5MZSiwb80fcHw=
112-github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
113-github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
114+github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
115+github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
116 github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
117 github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
118 github.com/charmbracelet/promwish v0.7.0 h1:oaMH+ey6W4DDIv1xucS8jL1ik/Q46qxjNXlh6XxEm+s=
119@@ -87,34 +89,37 @@ github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa h1:6rePgmsJguB6Z
120 github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa/go.mod h1:LmMZag2g7ILMmWtDmU7dIlctUopwmb73KpPzj0ip1uk=
121 github.com/charmbracelet/wish v1.4.3 h1:7FvNLoPGqiT7EdjQP4+XuvM1Hrnx9DyknilbD+Okx1s=
122 github.com/charmbracelet/wish v1.4.3/go.mod h1:hVgmhwhd52fLmO6m5AkREUMZYqQ0qmIJQDMe3HsNPmU=
123-github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY=
124-github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
125+github.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk=
126+github.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
127 github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U=
128 github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ=
129-github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3 h1:nsBhzPXBqeXEGZ9ztveSIPdf790BcDikbaEH3vMglH4=
130-github.com/charmbracelet/x/errors v0.0.0-20241007193646-7cc13b2883e3/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
131+github.com/charmbracelet/x/errors v0.0.0-20241101155414-3df16cb7eefd h1:sWN1wUxIICSfrMkXnYcAUkQ5CPVi5ZM12y2excuG9WU=
132+github.com/charmbracelet/x/errors v0.0.0-20241101155414-3df16cb7eefd/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
133+github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
134+github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
135 github.com/charmbracelet/x/input v0.2.0 h1:1Sv+y/flcqUfUH2PXNIDKDIdT2G8smOnGOgawqhwy8A=
136 github.com/charmbracelet/x/input v0.2.0/go.mod h1:KUSFIS6uQymtnr5lHVSOK9j8RvwTD4YHnWnzJUYnd/M=
137 github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
138 github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
139 github.com/charmbracelet/x/termios v0.1.0 h1:y4rjAHeFksBAfGbkRDmVinMg7x7DELIGAFbdNvxg97k=
140 github.com/charmbracelet/x/termios v0.1.0/go.mod h1:H/EVv/KRnrYjz+fCYa9bsKdqF3S8ouDK0AZEbG7r+/U=
141-github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
142-github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
143+github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
144+github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
145 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
146 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
147 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
148 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
149 github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878 h1:v8W8eW7eb2bHFXBA80UKcoe0TvEu46NlTHSDRvgAbMU=
150 github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878/go.mod h1:aGVXnhWpDlt5U4SphG97o1gszctZKvBTXy320E8Buw4=
151-github.com/delthas/go-localeinfo v0.0.0-20221116001557-686a1e185118 h1:Xzf9ra1QRJXD62gwudjI2iBq7x9CusvHd83Dg2OnUmE=
152 github.com/delthas/go-localeinfo v0.0.0-20221116001557-686a1e185118/go.mod h1:sG54BxlyQgIskYURLrg7mvhoGBe0Qq12DNtYRALwNa4=
153+github.com/delthas/go-localeinfo v0.0.0-20240813094314-e5413e186769 h1:wlT2rsyVbFCWOPGCIWlUTYERcZNaexWThJICJQLBMkU=
154+github.com/delthas/go-localeinfo v0.0.0-20240813094314-e5413e186769/go.mod h1:sG54BxlyQgIskYURLrg7mvhoGBe0Qq12DNtYRALwNa4=
155 github.com/delthas/tcell/v2 v2.4.1-0.20230710100648-1489e78d90fb h1:x0hrYPzXpmn3L/4QnW0UXJnHX9oz0OcZNcsSgregusw=
156 github.com/delthas/tcell/v2 v2.4.1-0.20230710100648-1489e78d90fb/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
157 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
158 github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
159-github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
160-github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
161+github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
162+github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
163 github.com/dsoprea/go-exif v0.0.0-20230826092837-6579e82b732d h1:ygcRCGNKuEiA98k7X35hknEN8RIRUF1jrz7k1rZCvsk=
164 github.com/dsoprea/go-exif v0.0.0-20230826092837-6579e82b732d/go.mod h1:lOaOt7+UEppOgyvRy749v3do836U/hw0YVJNjoyPaEs=
165 github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
166@@ -185,15 +190,15 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
167 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
168 github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
169 github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
170-github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw=
171-github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
172+github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
173+github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
174 github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
175 github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
176 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
177 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
178 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
179-github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
180-github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
181+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
182+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
183 github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
184 github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
185 github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
186@@ -217,7 +222,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
187 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
188 github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
189 github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
190-github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
191 github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
192 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
193 github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
194@@ -226,14 +230,14 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
195 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
196 github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
197 github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
198-github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
199-github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
200-github.com/minio/madmin-go/v3 v3.0.70 h1:zrFCXLcV6PR74JC0yytK4Dk2qsaCV8kXQoPTvcusR2k=
201-github.com/minio/madmin-go/v3 v3.0.70/go.mod h1:TOTc96ZkMknNhl+ReO/V68bQfgRGfH+8iy7YaDzHdXA=
202+github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
203+github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
204+github.com/minio/madmin-go/v3 v3.0.75 h1:m3D0jmGK7TUPjKM4bFqR8l2mabHCozH0Zy8ToIvgy88=
205+github.com/minio/madmin-go/v3 v3.0.75/go.mod h1:ku/RUc2xeo4Uui/GHUURMoNEVXk4Ih40xA3KHLyMF1o=
206 github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
207 github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
208-github.com/minio/minio-go/v7 v7.0.77 h1:GaGghJRg9nwDVlNbwYjSDJT1rqltQkBFDsypWX1v3Bw=
209-github.com/minio/minio-go/v7 v7.0.77/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg=
210+github.com/minio/minio-go/v7 v7.0.80 h1:2mdUHXEykRdY/BigLt3Iuu1otL0JTogT0Nmltg0wujk=
211+github.com/minio/minio-go/v7 v7.0.80/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0=
212 github.com/mmcdole/gofeed v1.3.0 h1:5yn+HeqlcvjMeAI4gu6T+crm7d0anY85+M+v6fIFNG4=
213 github.com/mmcdole/gofeed v1.3.0/go.mod h1:9TGv2LcJhdXePDzxiuMnukhV2/zb6VtnZt1mS+SjkLE=
214 github.com/mmcdole/goxpp v1.1.1 h1:RGIX+D6iQRIunGHrKqnA2+700XMCnNv0bAOOv5MUhx8=
215@@ -259,43 +263,41 @@ github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577 h1:hVmVNt
216 github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577/go.mod h1:G3Cu1AW+dmRLDFpOi8eUAfc3cGoRHUjTkGjeRcndgl4=
217 github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e h1:76Dng5ms0fR+26doKZAvNqhi2UPfnLxGfPIDEr+BBlM=
218 github.com/neurosnap/go-jpeg-image-structure v0.0.0-20221010133817-70b1c1ff679e/go.mod h1:nZBDA7+RD63GDJwjZmxhxac65MJqiCIHUUUvdYOsFkk=
219-github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
220-github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
221 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
222 github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
223 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoOvaNHPquFnRkdraEo7+8t6bW7nWEhlALnwZPdI=
224 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo=
225 github.com/picosh/pobj v0.0.0-20241016194248-c39198b2ff23 h1:NEJ5a4UXeF0/X7xmYNzXcwLQID9DwgazlqkMMC5zZ3M=
226 github.com/picosh/pobj v0.0.0-20241016194248-c39198b2ff23/go.mod h1:cF+eAl4G1vU+WOD8cYCKaxokHo6MWmbR8J4/SJnvESg=
227-github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed h1:aBJeQoLvq/V3hX6bgWjuuTmGzgbPNYuuwaCWU4aSJcU=
228-github.com/picosh/pubsub v0.0.0-20241008010300-a63fd95dc8ed/go.mod h1:ajolgob5MxlHdp5HllF7u3rTlCgER4InqfP7M/xl6HQ=
229-github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848 h1:VWbjNNOqpJ8AB3zdw+M5+XC/SINooWLGi6WCozKwt1o=
230-github.com/picosh/send v0.0.0-20241008013240-6fdbff00f848/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
231+github.com/picosh/pubsub v0.0.0-20241030185810-e24d08b67ab8 h1:E/eQsxdHBctPArAzjSHUAVZtDXjsD1AduGD94mbUJQg=
232+github.com/picosh/pubsub v0.0.0-20241030185810-e24d08b67ab8/go.mod h1:ajolgob5MxlHdp5HllF7u3rTlCgER4InqfP7M/xl6HQ=
233+github.com/picosh/send v0.0.0-20241107150437-0febb0049b4f h1:pdEh1Z7zH5Og9nS7jRuqwup3bcPsC6faDNQ6mgrV9ws=
234+github.com/picosh/send v0.0.0-20241107150437-0febb0049b4f/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
235 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs=
236 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0/go.mod h1:QaBDtybFC5gz7EG/9c3bgzuyW7W5W2rYLFZxWNuWk3Q=
237-github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e h1:3rNSjBJ6VlvngWF58V/z0fPLH7WyzKpSboC6YznECgw=
238-github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e/go.mod h1:UrDH/VCIc1wg/L6iY2zSYt4TiGw+25GsKSnkVkU40Dw=
239+github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9 h1:g5oZmnDFr11HarA8IAXcc4o9PBlolSM59QIATCSoato=
240+github.com/picosh/tunkit v0.0.0-20240905223921-532404cef9d9/go.mod h1:UrDH/VCIc1wg/L6iY2zSYt4TiGw+25GsKSnkVkU40Dw=
241 github.com/picosh/utils v0.0.0-20241018143404-b351d5d765f3 h1:1t/w0GrzwA3rkdotEsHbZIlCOv0T28qtO0U60/iOgQQ=
242 github.com/picosh/utils v0.0.0-20241018143404-b351d5d765f3/go.mod h1:ftrp1FjbKK/mFnBAYGymA1QEtPlkA0+lWkPI5h0HKt4=
243-github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
244-github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
245+github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM=
246+github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY=
247 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
248 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
249 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
250 github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
251 github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
252-github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
253-github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
254+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
255+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
256 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
257 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
258-github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
259-github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
260+github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
261+github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
262 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
263 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
264 github.com/prometheus/prom2json v1.4.1 h1:7McxdrHgPEOtMwWjkKtd0v5AhpR2Q6QAnlHKVxq0+tQ=
265 github.com/prometheus/prom2json v1.4.1/go.mod h1:CzOQykSKFxXuC7ELUZHOHQvwKesQ3eN0p2PWLhFitQM=
266-github.com/prometheus/prometheus v0.54.1 h1:vKuwQNjnYN2/mDoWfHXDhAsz/68q/dQDb+YbcEqU7MQ=
267-github.com/prometheus/prometheus v0.54.1/go.mod h1:xlLByHhk2g3ycakQGrMaU8K7OySZx98BzeCR99991NY=
268+github.com/prometheus/prometheus v0.55.0 h1:ITinOi1zr3HemoVWHf679PfRRmpxZOcR4nEvsze6eB0=
269+github.com/prometheus/prometheus v0.55.0/go.mod h1:GGS7QlWKCqCbcEzWsVahYIfQwiGhcExkarHyLJTsv6I=
270 github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
271 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
272 github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
273@@ -315,8 +317,8 @@ github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rR
274 github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=
275 github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
276 github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
277-github.com/sendgrid/sendgrid-go v3.14.0+incompatible h1:KDSasSTktAqMJCYClHVE94Fcif2i7P7wzISv1sU6DUA=
278-github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
279+github.com/sendgrid/sendgrid-go v3.16.0+incompatible h1:i8eE6IMkiCy7vusSdacHHSBUpXyTcTXy/Rl9N9aZ/Qw=
280+github.com/sendgrid/sendgrid-go v3.16.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
281 github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
282 github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
283 github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
284@@ -334,23 +336,23 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
285 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
286 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
287 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
288-github.com/tinylib/msgp v1.2.2 h1:iHiBE1tJQwFI740SPEPkGE8cfhNfrqOYRlH450BnC/4=
289-github.com/tinylib/msgp v1.2.2/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
290+github.com/tinylib/msgp v1.2.4 h1:yLFeUGostXXSGW5vxfT5dXG/qzkn4schv2I7at5+hVU=
291+github.com/tinylib/msgp v1.2.4/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
292 github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
293 github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
294 github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo=
295 github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI=
296-github.com/x-way/crawlerdetect v0.2.21 h1:LORs0nEy+MWUsC3XvKf00hXyO7drB5w/hlGB8bztXbI=
297-github.com/x-way/crawlerdetect v0.2.21/go.mod h1:DVupfue81iupuoUmFjIyDUqPqGaJhtZfYQDWoP1ZUR4=
298+github.com/x-way/crawlerdetect v0.2.24 h1:kZDzSeiXB64M+Bknopn5GddHT+LBocD61jEjqDOufLE=
299+github.com/x-way/crawlerdetect v0.2.24/go.mod h1:s6iUJZPq/WNBJThPRK+zk8ah7iIbGUZn9nYWMls3YP0=
300 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
301 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
302-github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
303 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
304 github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
305-github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U=
306 github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
307-github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s=
308-github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY=
309+github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
310+github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
311+github.com/yuin/goldmark-emoji v1.0.4 h1:vCwMkPZSNefSUnOW2ZKRUjBSD5Ok3W78IXhGxxAEF90=
312+github.com/yuin/goldmark-emoji v1.0.4/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
313 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
314 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
315 github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
316@@ -366,12 +368,12 @@ go.abhg.dev/goldmark/toc v0.10.0/go.mod h1:OpH0qqRP9v/eosCV28ZeqGI78jZ8rri3C7Jh8
317 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
318 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
319 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
320-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
321 golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
322+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
323 golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
324 golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
325-golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw=
326-golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
327+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
328+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
329 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
330 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
331 golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
332@@ -384,7 +386,6 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
333 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
334 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
335 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
336-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
337 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
338 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
339 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
340@@ -414,30 +415,30 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
341 golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
342 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
343 golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
344+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
345 golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
346 golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
347 golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
348 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
349 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
350-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
351 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
352 golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
353 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
354 golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
355+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
356 golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
357 golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
358 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
359 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
360 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
361-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
362 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
363 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
364 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
365 golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
366 golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
367 golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
368-golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
369-golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
370+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
371+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
372 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
373 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
374 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
M pipe/cli.go
+130, -39
  1@@ -19,7 +19,7 @@ import (
  2 	"github.com/picosh/pico/db"
  3 	"github.com/picosh/pico/shared"
  4 	psub "github.com/picosh/pubsub"
  5-	"github.com/picosh/send/utils"
  6+	gossh "golang.org/x/crypto/ssh"
  7 )
  8 
  9 func flagSet(cmdName string, sesh ssh.Session) *flag.FlagSet {
 10@@ -48,25 +48,6 @@ func NewTabWriter(out io.Writer) *tabwriter.Writer {
 11 	return tabwriter.NewWriter(out, 0, 0, 1, ' ', tabwriter.TabIndent)
 12 }
 13 
 14-func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
 15-	var err error
 16-	key, err := utils.KeyText(s)
 17-	if err != nil {
 18-		return nil, fmt.Errorf("key not found")
 19-	}
 20-
 21-	user, err := dbpool.FindUserForKey(s.User(), key)
 22-	if err != nil {
 23-		return nil, err
 24-	}
 25-
 26-	if user.Name == "" {
 27-		return nil, fmt.Errorf("must have username set")
 28-	}
 29-
 30-	return user, nil
 31-}
 32-
 33 // scope topic to user by prefixing name.
 34 func toTopic(userName, topic string) string {
 35 	return fmt.Sprintf("%s/%s", userName, topic)
 36@@ -117,6 +98,7 @@ type CliHandler struct {
 37 	PubSub  psub.PubSub
 38 	Cfg     *shared.ConfigSite
 39 	Waiters *syncmap.Map[string, []string]
 40+	Access  *syncmap.Map[string, []string]
 41 }
 42 
 43 func toSshCmd(cfg *shared.ConfigSite) string {
 44@@ -127,21 +109,46 @@ func toSshCmd(cfg *shared.ConfigSite) string {
 45 	return fmt.Sprintf("%s%s", port, cfg.Domain)
 46 }
 47 
 48+// parseArgList parses a comma separated list of arguments.
 49+func parseArgList(arg string) []string {
 50+	argList := strings.Split(arg, ",")
 51+	for i, acc := range argList {
 52+		argList[i] = strings.TrimSpace(acc)
 53+	}
 54+	return argList
 55+}
 56+
 57+// checkAccess checks if the user has access to a topic based on an access list.
 58+func checkAccess(accessList []string, userName string, sesh ssh.Session) bool {
 59+	for _, acc := range accessList {
 60+		if acc == userName {
 61+			return true
 62+		}
 63+
 64+		if key := sesh.PublicKey(); key != nil && acc == gossh.FingerprintSHA256(key) {
 65+			return true
 66+		}
 67+	}
 68+
 69+	return false
 70+}
 71+
 72 func WishMiddleware(handler *CliHandler) wish.Middleware {
 73-	dbpool := handler.DBPool
 74 	pubsub := handler.PubSub
 75 
 76 	return func(next ssh.Handler) ssh.Handler {
 77 		return func(sesh ssh.Session) {
 78 			logger := handler.Logger
 79 			ctx := sesh.Context()
 80-			user, err := getUser(sesh, dbpool)
 81+
 82+			user, err := shared.GetUser(ctx)
 83 			if err != nil {
 84-				utils.ErrorHandler(sesh, err)
 85-				return
 86+				logger.Info("user not found", "err", err)
 87 			}
 88 
 89-			logger = shared.LoggerWithUser(logger, user)
 90+			if user != nil {
 91+				logger = shared.LoggerWithUser(logger, user)
 92+			}
 93 
 94 			args := sesh.Command()
 95 
 96@@ -151,7 +158,19 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 97 				return
 98 			}
 99 
100-			isAdmin := handler.DBPool.HasFeatureForUser(user.ID, "admin")
101+			userName := "public"
102+
103+			userNameAddition := ""
104+
105+			isAdmin := false
106+			if user != nil {
107+				isAdmin = handler.DBPool.HasFeatureForUser(user.ID, "admin")
108+
109+				userName = user.Name
110+				if user.PublicKey.Name != "" {
111+					userNameAddition = fmt.Sprintf("-%s", user.PublicKey.Name)
112+				}
113+			}
114 
115 			cmd := strings.TrimSpace(args[0])
116 			if cmd == "help" {
117@@ -159,7 +178,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
118 				next(sesh)
119 				return
120 			} else if cmd == "ls" {
121-				topicFilter := fmt.Sprintf("%s/", user.Name)
122+				if userName == "public" {
123+					wish.Fatalln(sesh, "access denied")
124+					return
125+				}
126+
127+				topicFilter := fmt.Sprintf("%s/", userName)
128 				if isAdmin {
129 					topicFilter = ""
130 				}
131@@ -186,7 +210,13 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
132 					if len(channels) > 0 || len(waitingChannels) > 0 {
133 						outputData += "Channel Information\r\n"
134 						for _, channel := range channels {
135-							outputData += fmt.Sprintf("- %s:\r\n", channel.Topic)
136+							extraData := ""
137+
138+							if accessList, ok := handler.Access.Load(channel.Topic); ok {
139+								extraData += fmt.Sprintf(" (Access List: %s)", strings.Join(accessList, ", "))
140+							}
141+
142+							outputData += fmt.Sprintf("- %s:%s\r\n", channel.Topic, extraData)
143 							outputData += "  Clients:\r\n"
144 
145 							var pubs []*psub.Client
146@@ -208,7 +238,13 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
147 						}
148 
149 						for waitingChannel, channelPubs := range waitingChannels {
150-							outputData += fmt.Sprintf("- %s:\r\n", waitingChannel)
151+							extraData := ""
152+
153+							if accessList, ok := handler.Access.Load(waitingChannel); ok {
154+								extraData += fmt.Sprintf(" (Access List: %s)", strings.Join(accessList, ", "))
155+							}
156+
157+							outputData += fmt.Sprintf("- %s:%s\r\n", waitingChannel, extraData)
158 							outputData += "  Clients:\r\n"
159 							outputData += fmt.Sprintf("    %s:\r\n", "Waiting Pubs")
160 							for _, client := range channelPubs {
161@@ -239,16 +275,11 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
162 				"cmdArgs", cmdArgs,
163 			)
164 
165-			userName := user.Name
166-
167-			if user.PublicKey.Name != "" {
168-				userName += fmt.Sprintf("-%s", user.PublicKey.Name)
169-			}
170-
171-			clientID := fmt.Sprintf("%s (%s@%s)", uuid.NewString(), userName, sesh.RemoteAddr().String())
172+			clientID := fmt.Sprintf("%s (%s%s@%s)", uuid.NewString(), userName, userNameAddition, sesh.RemoteAddr().String())
173 
174 			if cmd == "pub" {
175 				pubCmd := flagSet("pub", sesh)
176+				access := pubCmd.String("a", "", "Comma separated list of pico usernames or ssh-key fingerprints to allow access to a topic")
177 				empty := pubCmd.Bool("e", false, "Send an empty message to subs")
178 				public := pubCmd.Bool("p", false, "Publish message to public topic")
179 				block := pubCmd.Bool("b", true, "Block writes until a subscriber is available")
180@@ -269,8 +300,15 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
181 					"block", *block,
182 					"timeout", *timeout,
183 					"topic", topic,
184+					"access", *access,
185 				)
186 
187+				var accessList []string
188+
189+				if *access != "" {
190+					accessList = parseArgList(*access)
191+				}
192+
193 				var rw io.ReadWriter
194 				if *empty {
195 					rw = bytes.NewBuffer(make([]byte, 1))
196@@ -282,16 +320,28 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
197 					topic = uuid.NewString()
198 				}
199 
200+				var withoutUser string
201 				var name string
202 				msgFlag := ""
203 
204 				if isAdmin && strings.HasPrefix(topic, "/") {
205 					name = strings.TrimPrefix(topic, "/")
206 				} else {
207-					name = toTopic(user.Name, topic)
208+					name = toTopic(userName, topic)
209 					if *public {
210 						name = toPublicTopic(topic)
211 						msgFlag = "-p "
212+					} else {
213+						withoutUser = topic
214+					}
215+				}
216+
217+				if len(accessList) > 0 && !*public {
218+					_, loaded := handler.Access.LoadOrStore(name, accessList)
219+					if !loaded {
220+						defer func() {
221+							handler.Access.Delete(name)
222+						}()
223 					}
224 				}
225 
226@@ -303,6 +353,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
227 					topic,
228 				)
229 
230+				if accessList, ok := handler.Access.Load(withoutUser); !isAdmin && !*public && ok {
231+					if checkAccess(accessList, userName, sesh) {
232+						name = withoutUser
233+					}
234+				}
235+
236 				var pubCtx context.Context = ctx
237 
238 				if *block {
239@@ -425,14 +481,23 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
240 					"topic", topic,
241 				)
242 
243+				var withoutUser string
244 				var name string
245 
246 				if isAdmin && strings.HasPrefix(topic, "/") {
247 					name = strings.TrimPrefix(topic, "/")
248 				} else {
249-					name = toTopic(user.Name, topic)
250+					name = toTopic(userName, topic)
251 					if *public {
252 						name = toPublicTopic(topic)
253+					} else {
254+						withoutUser = topic
255+					}
256+				}
257+
258+				if accessList, ok := handler.Access.Load(withoutUser); !isAdmin && !*public && ok {
259+					if checkAccess(accessList, userName, sesh) {
260+						name = withoutUser
261 					}
262 				}
263 
264@@ -451,6 +516,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
265 				}
266 			} else if cmd == "pipe" {
267 				pipeCmd := flagSet("pipe", sesh)
268+				access := pipeCmd.String("a", "", "Comma separated list of pico usernames or ssh-key fingerprints to allow access to a topic")
269 				public := pipeCmd.Bool("p", false, "Pipe to a public topic")
270 				replay := pipeCmd.Bool("r", false, "Replay messages to the client that sent it")
271 				if !flagCheck(pipeCmd, topic, cmdArgs) {
272@@ -467,23 +533,42 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
273 					"public", *public,
274 					"replay", *replay,
275 					"topic", topic,
276+					"access", *access,
277 				)
278 
279+				var accessList []string
280+
281+				if *access != "" {
282+					accessList = parseArgList(*access)
283+				}
284+
285 				isCreator := topic == ""
286 				if isCreator {
287 					topic = uuid.NewString()
288 				}
289 
290+				var withoutUser string
291 				var name string
292 				flagMsg := ""
293 
294 				if isAdmin && strings.HasPrefix(topic, "/") {
295 					name = strings.TrimPrefix(topic, "/")
296 				} else {
297-					name = toTopic(user.Name, topic)
298+					name = toTopic(userName, topic)
299 					if *public {
300 						name = toPublicTopic(topic)
301 						flagMsg = "-p "
302+					} else {
303+						withoutUser = topic
304+					}
305+				}
306+
307+				if len(accessList) > 0 && !*public {
308+					_, loaded := handler.Access.LoadOrStore(name, accessList)
309+					if !loaded {
310+						defer func() {
311+							handler.Access.Delete(name)
312+						}()
313 					}
314 				}
315 
316@@ -497,6 +582,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
317 					)
318 				}
319 
320+				if accessList, ok := handler.Access.Load(withoutUser); !isAdmin && !*public && ok {
321+					if checkAccess(accessList, userName, sesh) {
322+						name = withoutUser
323+					}
324+				}
325+
326 				readErr, writeErr := pubsub.Pipe(
327 					ctx,
328 					clientID,
M pipe/ssh.go
+6, -1
 1@@ -10,6 +10,7 @@ import (
 2 
 3 	"github.com/antoniomika/syncmap"
 4 	"github.com/charmbracelet/promwish"
 5+	"github.com/charmbracelet/ssh"
 6 	"github.com/charmbracelet/wish"
 7 	"github.com/picosh/pico/db/postgres"
 8 	"github.com/picosh/pico/shared"
 9@@ -38,13 +39,17 @@ func StartSshServer() {
10 		PubSub:  pubsub,
11 		Cfg:     cfg,
12 		Waiters: syncmap.New[string, []string](),
13+		Access:  syncmap.New[string, []string](),
14 	}
15 
16 	sshAuth := shared.NewSshAuthHandler(dbh, logger, cfg)
17 	s, err := wish.NewServer(
18 		wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
19 		wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
20-		wish.WithPublicKeyAuth(sshAuth.PubkeyAuthHandler),
21+		wish.WithPublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
22+			sshAuth.PubkeyAuthHandler(ctx, key)
23+			return true
24+		}),
25 		wish.WithMiddleware(
26 			WishMiddleware(handler),
27 			promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "pipe-ssh"),
M shared/mdparser.go
+1, -1
1@@ -413,7 +413,7 @@ func AstTitle(doc ast.Node, src []byte, clean bool) string {
2 					p := h.Parent()
3 					p.RemoveChild(p, n)
4 				}
5-				out = string(h.Text(src))
6+				out = string(h.Lines().Value(src))
7 			}
8 			return ast.WalkStop, nil
9 		}