Compare commits
63
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b855ceddd | ||
|
|
e30d4da455 | ||
|
|
26e6e57949 | ||
|
|
b572966bc4 | ||
|
|
bbfa4f1043 | ||
|
|
9ad4f0b75e | ||
|
|
2093f4ece2 | ||
|
|
7bc7703dc2 | ||
|
|
0ed7452e77 | ||
|
|
366cc19c1b | ||
|
|
c72f30eabb | ||
|
|
235f0dade0 | ||
|
|
9c718cbc5f | ||
|
|
02de92afc7 | ||
|
|
add01455fb | ||
|
|
497f3ce47f | ||
|
|
64188e5713 | ||
|
|
33a6d6da97 | ||
|
|
6410e3be85 | ||
|
|
136d7e8215 | ||
|
|
d3fdd7b0d8 | ||
|
|
329fcc204c | ||
|
|
ba2c7894a8 | ||
|
|
07667c8881 | ||
|
|
68504a70a0 | ||
|
|
32073b3d66 | ||
|
|
d1c1664a38 | ||
|
|
8cbcff98ec | ||
|
|
26f82ad95c | ||
|
|
1b90604b2d | ||
|
|
a03c002df4 | ||
|
|
1ce9415d34 | ||
|
|
cc842901b3 | ||
|
|
23d7e4cdbb | ||
|
|
b48f8fca31 | ||
|
|
a4da93326e | ||
|
|
8bd5c0d163 | ||
|
|
972ab87247 | ||
|
|
d1ea664b41 | ||
|
|
a55fadd53a | ||
|
|
c70a66a1c5 | ||
|
|
8357846818 | ||
|
|
31ea91afb8 | ||
|
|
6616541f65 | ||
|
|
01695822bb | ||
|
|
f0186d1aab | ||
|
|
41a3359085 | ||
|
|
d6cce8df2c | ||
|
|
596861a594 | ||
|
|
385ea800a4 | ||
|
|
27fc339e36 | ||
|
|
61e2173f25 | ||
|
|
13a3fc3d1b | ||
|
|
6a1b515ea9 | ||
|
|
82f27e6b63 | ||
|
|
6ac75031ad | ||
|
|
8b7f1331ee | ||
|
|
099aad8475 | ||
|
|
c1b3fba344 | ||
|
|
d7e9be99f9 | ||
|
|
067a8bcb21 | ||
|
|
f5569a62f1 | ||
|
|
1ab1ed8a82 |
@@ -21,8 +21,10 @@ compose-dev-backend.yml
|
||||
compose-dev-frontend.yml
|
||||
compose-private-backend.yml
|
||||
compose-private-frontend.yml
|
||||
compose-e2e-test.yml
|
||||
compose-private.yml
|
||||
rest-client.env.json
|
||||
Makefile
|
||||
|
||||
# generated files
|
||||
*.cov
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
|
||||
@@ -32,34 +32,42 @@ jobs:
|
||||
- name: install go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: "1.20"
|
||||
|
||||
- name: install golangci-lint and goveralls
|
||||
run: |
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $GITHUB_WORKSPACE v1.49.0
|
||||
go install github.com/mattn/goveralls@latest
|
||||
|
||||
- name: test and lint backend
|
||||
- name: test and build backend
|
||||
run: |
|
||||
go test -race -timeout=60s -covermode=atomic -coverprofile=$GITHUB_WORKSPACE/profile.cov_tmp ./...
|
||||
cat $GITHUB_WORKSPACE/profile.cov_tmp | grep -v "_mock.go" > $GITHUB_WORKSPACE/profile.cov
|
||||
$GITHUB_WORKSPACE/golangci-lint --config ${GITHUB_WORKSPACE}/backend/.golangci.yml run --out-format=github-actions ./...
|
||||
go build -race ./...
|
||||
working-directory: backend/app
|
||||
env:
|
||||
TZ: "America/Chicago"
|
||||
|
||||
- name: test and lint examples
|
||||
- name: test examples
|
||||
run: |
|
||||
go version
|
||||
$GITHUB_WORKSPACE/golangci-lint version
|
||||
go test -race ./...
|
||||
$GITHUB_WORKSPACE/golangci-lint --config ${GITHUB_WORKSPACE}/backend/.golangci.yml run --out-format=github-actions ./...
|
||||
go build -race ./...
|
||||
working-directory: backend/_example/memory_store
|
||||
env:
|
||||
TZ: "America/Chicago"
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
||||
working-directory: backend/app
|
||||
|
||||
- name: golangci-lint on example directory
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
||||
args: --config ../../.golangci.yml
|
||||
working-directory: backend/_example/memory_store
|
||||
|
||||
- name: submit coverage
|
||||
run: goveralls -service="github" -coverprofile=$GITHUB_WORKSPACE/profile.cov
|
||||
run: |
|
||||
go install github.com/mattn/goveralls@latest
|
||||
goveralls -service="github" -coverprofile=$GITHUB_WORKSPACE/profile.cov
|
||||
working-directory: backend
|
||||
env:
|
||||
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -165,10 +165,11 @@ jobs:
|
||||
run_install: false
|
||||
|
||||
- name: Check bundle size
|
||||
uses: andresz1/size-limit-action@v1
|
||||
uses: andresz1/size-limit-action@dd31dce7dcc72a041fd3e49abf0502b13fc4ce05
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
directory: ./frontend/apps/remark42
|
||||
package_manager: pnpm
|
||||
|
||||
test:
|
||||
name: Tests & Coverage
|
||||
|
||||
@@ -25,3 +25,4 @@ compose-private.yml
|
||||
/backend/_example/*/vendor
|
||||
http-client.env.json
|
||||
/playwright-report/
|
||||
/backend/app/cmd/var
|
||||
|
||||
+4
-4
@@ -11,7 +11,7 @@ COPY ./frontend/apps/remark42/package.json /srv/frontend/apps/remark42/
|
||||
RUN \
|
||||
if [[ -z "$SKIP_FRONTEND_BUILD" || -z "$SKIP_FRONTEND_TEST" ]]; then \
|
||||
apk add --no-cache --update git && \
|
||||
npm i -g pnpm; \
|
||||
npm i -g pnpm@7; \
|
||||
fi
|
||||
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.pnpm-store/v3 \
|
||||
@@ -45,7 +45,7 @@ RUN \
|
||||
echo 'Skip frontend build'; \
|
||||
fi
|
||||
|
||||
FROM umputun/baseimage:buildgo-v1.9.2 as build-backend
|
||||
FROM umputun/baseimage:buildgo-v1.11.0 as build-backend
|
||||
|
||||
ARG CI
|
||||
ARG GITHUB_REF
|
||||
@@ -70,7 +70,7 @@ RUN \
|
||||
cd app && \
|
||||
if [ -z "$SKIP_BACKEND_TEST" ] ; then \
|
||||
CGO_ENABLED=1 go test -race -p 1 -timeout="${BACKEND_TEST_TIMEOUT:-300s}" -covermode=atomic -coverprofile=/profile.cov_tmp ./... && \
|
||||
cat /profile.cov_tmp | grep -v "_mock.go" > /profile.cov ; \
|
||||
cat /profile.cov_tmp | grep -v "_mock.go" > /profile.cov && \
|
||||
golangci-lint run --config ../.golangci.yml ./... ; \
|
||||
else \
|
||||
echo "skip backend tests and linter" \
|
||||
@@ -81,7 +81,7 @@ RUN \
|
||||
echo "version=$version" && \
|
||||
go build -o remark42 -ldflags "-X main.revision=${version} -s -w" ./app
|
||||
|
||||
FROM umputun/baseimage:app-v1.9.2
|
||||
FROM umputun/baseimage:app-v1.11.0
|
||||
|
||||
ARG GITHUB_SHA
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ WORKDIR /srv/frontend
|
||||
COPY ./frontend/package.json ./frontend/pnpm-lock.yaml ./frontend/pnpm-workspace.yaml /srv/frontend/
|
||||
COPY ./frontend/apps/remark42/package.json /srv/frontend/apps/remark42/package.json
|
||||
|
||||
RUN apk add --no-cache --update git && npm i -g pnpm
|
||||
RUN apk add --no-cache --update git && npm i -g pnpm@7
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.pnpm-store/v3 pnpm i
|
||||
|
||||
FROM frontend-deps AS build-frontend
|
||||
|
||||
@@ -49,4 +49,7 @@ rundev:
|
||||
docker-compose -f compose-private.yml build
|
||||
docker-compose -f compose-private.yml up
|
||||
|
||||
e2e:
|
||||
docker compose -f compose-e2e-test.yml up --build --quiet-pull --exit-code-from tests
|
||||
|
||||
.PHONY: bin backend
|
||||
|
||||
@@ -35,7 +35,8 @@ func NewMemAdminStore(key string) *MemAdmin {
|
||||
return &MemAdmin{data: map[string]AdminRec{}, key: key}
|
||||
}
|
||||
|
||||
// Key executes find by siteID and returns substructure with secret key
|
||||
// Key supposed to execute find by siteID and returns substructure with secret key,
|
||||
// but in this case the shared secret is used for all sites
|
||||
func (m *MemAdmin) Key(_ string) (key string, err error) {
|
||||
return m.key, nil
|
||||
}
|
||||
|
||||
@@ -624,6 +624,7 @@ func TestMemData_DeleteComment(t *testing.T) {
|
||||
func TestMemData_Close(t *testing.T) {
|
||||
b := prepMem(t)
|
||||
assert.NoError(t, b.Close())
|
||||
assert.NoError(t, b.Close(), "second call should not result in panic or errors")
|
||||
}
|
||||
|
||||
func TestMemData_DeleteHard(t *testing.T) {
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
module github.com/umputun/remark42/memory_store
|
||||
|
||||
go 1.17
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/go-pkgz/jrpc v0.3.0
|
||||
github.com/go-pkgz/lgr v0.10.4
|
||||
github.com/go-pkgz/lgr v0.11.0
|
||||
github.com/jessevdk/go-flags v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/umputun/remark42/backend v1.10.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/umputun/remark42/backend v1.1000.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Depado/bfchroma/v2 v2.0.0 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.8.0 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.8.1 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.3.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.8.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/didip/tollbooth/v7 v7.0.1 // indirect
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.7 // indirect
|
||||
github.com/go-chi/render v1.0.2 // indirect
|
||||
github.com/go-pkgz/expirable-cache v0.1.0 // indirect
|
||||
github.com/go-pkgz/rest v1.16.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.10 // indirect
|
||||
github.com/go-chi/render v1.0.3 // indirect
|
||||
github.com/go-pkgz/expirable-cache v1.0.0 // indirect
|
||||
github.com/go-pkgz/rest v1.17.0 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.20 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82 // indirect
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
golang.org/x/image v0.11.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/umputun/remark42/backend => ../../
|
||||
replace github.com/umputun/remark42/backend v1.1000.0 => ../../
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
github.com/Depado/bfchroma/v2 v2.0.0 h1:IRpN9BPkNwEpR6w1ectIcNWOuhDSLx+8f1pn83fzxx8=
|
||||
github.com/Depado/bfchroma/v2 v2.0.0/go.mod h1:wFwW/Pw8Tnd0irzgO9Zxtxgzp3aPS8qBWlyadxujxmw=
|
||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0 h1:83xfxrnjv8eK+Cf8qZDzNo3PPF9IbTWHs7z28GY6D0U=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0/go.mod h1:mZxeWZlxP2Dy+/8cBob2PYd8O2DwNAzave5AY7A2eQw=
|
||||
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
|
||||
github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264=
|
||||
github.com/alecthomas/chroma/v2 v2.8.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw=
|
||||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
|
||||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -19,22 +21,24 @@ github.com/didip/tollbooth/v7 v7.0.1 h1:TkT4sBKoQoHQFPf7blQ54iHrZiTDnr8TceU+MulV
|
||||
github.com/didip/tollbooth/v7 v7.0.1/go.mod h1:VZhDSGl5bDSPj4wPsih3PFa4Uh9Ghv8hgacaTm5PRT4=
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f h1:jtKwihcLmUC9BAhoJ9adCUqdSSZcOdH2KL7mPTUm2aw=
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f/go.mod h1:q9C80dnsuVRP2dAskjnXRNWdUJqtGgwG9wNrzt0019s=
|
||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
|
||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
|
||||
github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg=
|
||||
github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-pkgz/expirable-cache v0.1.0 h1:3bw0m8vlTK8qlwz5KXuygNBTkiKRTPrAGXU0Ej2AC1g=
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-pkgz/expirable-cache v0.1.0/go.mod h1:GTrEl0X+q0mPNqN6dtcQXksACnzCBQ5k/k1SwXJsZKs=
|
||||
github.com/go-pkgz/expirable-cache v1.0.0 h1:ns5+1hjY8hntGv8bPaQd9Gr7Jyo+Uw5SLyII40aQdtA=
|
||||
github.com/go-pkgz/expirable-cache v1.0.0/go.mod h1:GTrEl0X+q0mPNqN6dtcQXksACnzCBQ5k/k1SwXJsZKs=
|
||||
github.com/go-pkgz/jrpc v0.3.0 h1:Fls38KqPsHzvp0FWfivr6cGnncC+iFBodHBqvUPY+0U=
|
||||
github.com/go-pkgz/jrpc v0.3.0/go.mod h1:MFtKs75JESiSqVicsQkgN2iDFFuCd3gVT1/vKiwRi00=
|
||||
github.com/go-pkgz/lgr v0.10.4 h1:l7qyFjqEZgwRgaQQSEp6tve4A3OU80VrfzpvtEX8ngw=
|
||||
github.com/go-pkgz/lgr v0.10.4/go.mod h1:CD0s1z6EFpIUplV067gitF77tn25JItzwHNKAPqeCF0=
|
||||
github.com/go-pkgz/lgr v0.11.0 h1:9XH5o+vj09L0sRWEswIGK1lJ6g07xVB4/Z28RV9Z+qM=
|
||||
github.com/go-pkgz/lgr v0.11.0/go.mod h1:4rdRmMSs4yGFjnUg0rSDbKx21LmFNZoH4y8OLl3qDnU=
|
||||
github.com/go-pkgz/rest v1.15.6/go.mod h1:KUWAqbDteYGS/CiXftomQsKjtEOifXsJ36Ka0skYbmk=
|
||||
github.com/go-pkgz/rest v1.16.0 h1:3An51XJXUq1XtICHvfAEp048ZCbUHBEga3g0WEu3zK0=
|
||||
github.com/go-pkgz/rest v1.16.0/go.mod h1:HHlLOt02NJc2sgffXBF6hYVMcRo4Gz3vjg43zTzN7VM=
|
||||
github.com/go-pkgz/rest v1.17.0 h1:LoBI/lDBMuqwWhOOkc6thM9NnwJO+K9nWvCOjZ7BAgE=
|
||||
github.com/go-pkgz/rest v1.17.0/go.mod h1:HHlLOt02NJc2sgffXBF6hYVMcRo4Gz3vjg43zTzN7VM=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -42,6 +46,7 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@@ -49,39 +54,70 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.6.1/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.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -338,6 +338,6 @@ func TestRPC_closeHndl(t *testing.T) {
|
||||
api := fmt.Sprintf("http://localhost:%d/test", port)
|
||||
|
||||
re := engine.RPC{Client: jrpc.Client{API: api, Client: http.Client{Timeout: 1 * time.Second}}}
|
||||
err := re.Close()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, re.Close())
|
||||
assert.NoError(t, re.Close(), "second call should not result in panic or errors")
|
||||
}
|
||||
|
||||
+78
-48
@@ -96,16 +96,17 @@ type ServerCommand struct {
|
||||
SendJWTHeader bool `long:"send-jwt-header" env:"SEND_JWT_HEADER" description:"send JWT as a header instead of cookie"`
|
||||
SameSite string `long:"same-site" env:"SAME_SITE" description:"set same site policy for cookies" choice:"default" choice:"none" choice:"lax" choice:"strict" default:"default"` // nolint
|
||||
|
||||
Google AuthGroup `group:"google" namespace:"google" env-namespace:"GOOGLE" description:"Google OAuth"`
|
||||
Github AuthGroup `group:"github" namespace:"github" env-namespace:"GITHUB" description:"Github OAuth"`
|
||||
Facebook AuthGroup `group:"facebook" namespace:"facebook" env-namespace:"FACEBOOK" description:"Facebook OAuth"`
|
||||
Microsoft AuthGroup `group:"microsoft" namespace:"microsoft" env-namespace:"MICROSOFT" description:"Microsoft OAuth"`
|
||||
Yandex AuthGroup `group:"yandex" namespace:"yandex" env-namespace:"YANDEX" description:"Yandex OAuth"`
|
||||
Twitter AuthGroup `group:"twitter" namespace:"twitter" env-namespace:"TWITTER" description:"Twitter OAuth"`
|
||||
Patreon AuthGroup `group:"patreon" namespace:"patreon" env-namespace:"PATREON" description:"Patreon OAuth"`
|
||||
Telegram bool `long:"telegram" env:"TELEGRAM" description:"Enable Telegram auth (using token from telegram.token)"`
|
||||
Dev bool `long:"dev" env:"DEV" description:"enable dev (local) oauth2"`
|
||||
Anonymous bool `long:"anon" env:"ANON" description:"enable anonymous login"`
|
||||
Apple AppleGroup `group:"apple" namespace:"apple" env-namespace:"APPLE" description:"Apple OAuth"`
|
||||
Google AuthGroup `group:"google" namespace:"google" env-namespace:"GOOGLE" description:"Google OAuth"`
|
||||
Github AuthGroup `group:"github" namespace:"github" env-namespace:"GITHUB" description:"Github OAuth"`
|
||||
Facebook AuthGroup `group:"facebook" namespace:"facebook" env-namespace:"FACEBOOK" description:"Facebook OAuth"`
|
||||
Microsoft AuthGroup `group:"microsoft" namespace:"microsoft" env-namespace:"MICROSOFT" description:"Microsoft OAuth"`
|
||||
Yandex AuthGroup `group:"yandex" namespace:"yandex" env-namespace:"YANDEX" description:"Yandex OAuth"`
|
||||
Twitter AuthGroup `group:"twitter" namespace:"twitter" env-namespace:"TWITTER" description:"Twitter OAuth"`
|
||||
Patreon AuthGroup `group:"patreon" namespace:"patreon" env-namespace:"PATREON" description:"Patreon OAuth"`
|
||||
Telegram bool `long:"telegram" env:"TELEGRAM" description:"Enable Telegram auth (using token from telegram.token)"`
|
||||
Dev bool `long:"dev" env:"DEV" description:"enable dev (local) oauth2"`
|
||||
Anonymous bool `long:"anon" env:"ANON" description:"enable anonymous login"`
|
||||
Email struct {
|
||||
Enable bool `long:"enable" env:"ENABLE" description:"enable auth via email"`
|
||||
From string `long:"from" env:"FROM" description:"from email address"`
|
||||
@@ -133,6 +134,14 @@ type ImageProxyGroup struct {
|
||||
CacheExternal bool `long:"cache-external" env:"CACHE_EXTERNAL" description:"enable caching for external images"`
|
||||
}
|
||||
|
||||
// AppleGroup defines options for Apple auth params
|
||||
type AppleGroup struct {
|
||||
CID string `long:"cid" env:"CID" description:"Apple client ID"`
|
||||
TID string `long:"tid" env:"TID" description:"Apple service ID"`
|
||||
KID string `long:"kid" env:"KID" description:"Private key ID"`
|
||||
PrivateKeyFilePath string `long:"private-key-filepath" env:"PRIVATE_KEY_FILEPATH" description:"Private key file location" default:"/srv/var/apple.p8"`
|
||||
}
|
||||
|
||||
// AuthGroup defines options group for auth params
|
||||
type AuthGroup struct {
|
||||
CID string `long:"cid" env:"CID" description:"OAuth client ID"`
|
||||
@@ -197,7 +206,7 @@ type AdminGroup struct {
|
||||
Admins []string `long:"id" env:"ID" description:"admin(s) ids" env-delim:","`
|
||||
Email []string `long:"email" env:"EMAIL" description:"admin emails" env-delim:","`
|
||||
} `group:"shared" namespace:"shared" env-namespace:"SHARED"`
|
||||
RPC RPCGroup `group:"rpc" namespace:"rpc" env-namespace:"RPC"`
|
||||
RPC AdminRPCGroup `group:"rpc" namespace:"rpc" env-namespace:"RPC"`
|
||||
}
|
||||
|
||||
// TelegramGroup defines token for Telegram used in notify and auth modules
|
||||
@@ -265,6 +274,12 @@ type RPCGroup struct {
|
||||
AuthPassword string `long:"auth_passwd" env:"AUTH_PASSWD" description:"basic auth user password"`
|
||||
}
|
||||
|
||||
// AdminRPCGroup defines options for remote admin store
|
||||
type AdminRPCGroup struct {
|
||||
RPCGroup
|
||||
SecretPerSite bool `long:"secret_per_site" env:"SECRET_PER_SITE" description:"enable JWT secret retrieval per aud, which is site_id in this case"`
|
||||
}
|
||||
|
||||
// LoadingCache defines interface for caching
|
||||
type LoadingCache interface {
|
||||
Get(key cache.Key, fn func() ([]byte, error)) (data []byte, err error) // load from cache if found or put to cache and return
|
||||
@@ -510,11 +525,12 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) {
|
||||
authenticator := s.getAuthenticator(dataService, avatarStore, adminStore, authRefreshCache)
|
||||
|
||||
telegramAuth := s.makeTelegramAuth(authenticator) // telegram auth requires TelegramAPI listener which is constructed below
|
||||
telegramService, telegramBotUsername := s.startTelegramAuthAndNotify(ctx, telegramAuth)
|
||||
telegramService := s.startTelegramAuthAndNotify(ctx, telegramAuth)
|
||||
|
||||
err = s.addAuthProviders(authenticator)
|
||||
if err != nil {
|
||||
_ = dataService.Close()
|
||||
_ = authRefreshCache.Close()
|
||||
return nil, fmt.Errorf("failed to make authenticator: %w", err)
|
||||
}
|
||||
|
||||
@@ -554,37 +570,38 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) {
|
||||
sslConfig, err := s.makeSSLConfig()
|
||||
if err != nil {
|
||||
_ = dataService.Close()
|
||||
_ = authRefreshCache.Close()
|
||||
return nil, fmt.Errorf("failed to make config of ssl server params: %w", err)
|
||||
}
|
||||
|
||||
srv := &api.Rest{
|
||||
Version: s.Revision,
|
||||
DataService: dataService,
|
||||
WebRoot: s.WebRoot,
|
||||
WebFS: webFS,
|
||||
RemarkURL: s.RemarkURL,
|
||||
ImageProxy: imgProxy,
|
||||
CommentFormatter: commentFormatter,
|
||||
Migrator: migr,
|
||||
ReadOnlyAge: s.ReadOnlyAge,
|
||||
SharedSecret: s.SharedSecret,
|
||||
Authenticator: authenticator,
|
||||
Cache: loadingCache,
|
||||
NotifyService: notifyService,
|
||||
TelegramService: telegramService,
|
||||
SSLConfig: sslConfig,
|
||||
UpdateLimiter: s.UpdateLimit,
|
||||
ImageService: imageService,
|
||||
EmailNotifications: contains("email", s.Notify.Users),
|
||||
TelegramBotUsername: telegramBotUsername,
|
||||
EmojiEnabled: s.EnableEmoji,
|
||||
AnonVote: s.AnonymousVote && s.RestrictVoteIP,
|
||||
SimpleView: s.SimpleView,
|
||||
ProxyCORS: s.ProxyCORS,
|
||||
AllowedAncestors: s.AllowedHosts,
|
||||
SendJWTHeader: s.Auth.SendJWTHeader,
|
||||
SubscribersOnly: s.SubscribersOnly,
|
||||
DisableSignature: s.DisableSignature,
|
||||
Version: s.Revision,
|
||||
DataService: dataService,
|
||||
WebRoot: s.WebRoot,
|
||||
WebFS: webFS,
|
||||
RemarkURL: s.RemarkURL,
|
||||
ImageProxy: imgProxy,
|
||||
CommentFormatter: commentFormatter,
|
||||
Migrator: migr,
|
||||
ReadOnlyAge: s.ReadOnlyAge,
|
||||
SharedSecret: s.SharedSecret,
|
||||
Authenticator: authenticator,
|
||||
Cache: loadingCache,
|
||||
NotifyService: notifyService,
|
||||
TelegramService: telegramService,
|
||||
SSLConfig: sslConfig,
|
||||
UpdateLimiter: s.UpdateLimit,
|
||||
ImageService: imageService,
|
||||
EmailNotifications: contains("email", s.Notify.Users),
|
||||
TelegramNotifications: contains("telegram", s.Notify.Users) && telegramService != nil,
|
||||
EmojiEnabled: s.EnableEmoji,
|
||||
AnonVote: s.AnonymousVote && s.RestrictVoteIP,
|
||||
SimpleView: s.SimpleView,
|
||||
ProxyCORS: s.ProxyCORS,
|
||||
AllowedAncestors: s.AllowedHosts,
|
||||
SendJWTHeader: s.Auth.SendJWTHeader,
|
||||
SubscribersOnly: s.SubscribersOnly,
|
||||
DisableSignature: s.DisableSignature,
|
||||
}
|
||||
|
||||
srv.ScoreThresholds.Low, srv.ScoreThresholds.Critical = s.LowScore, s.CriticalScore
|
||||
@@ -594,6 +611,7 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) {
|
||||
da, errDevAuth := authenticator.DevAuth()
|
||||
if errDevAuth != nil {
|
||||
_ = dataService.Close()
|
||||
_ = authRefreshCache.Close()
|
||||
return nil, fmt.Errorf("can't make dev oauth2 server: %w", errDevAuth)
|
||||
}
|
||||
devAuth = da
|
||||
@@ -829,12 +847,28 @@ func (s *ServerCommand) makeCache() (LoadingCache, error) {
|
||||
return nil, fmt.Errorf("unsupported cache type %s", s.Cache.Type)
|
||||
}
|
||||
|
||||
//nolint:gocyclo // simple code but many if checks
|
||||
func (s *ServerCommand) addAuthProviders(authenticator *auth.Service) error {
|
||||
providersCount := 0
|
||||
if s.Auth.Telegram {
|
||||
providersCount++
|
||||
}
|
||||
|
||||
if s.Auth.Apple.CID != "" && s.Auth.Apple.TID != "" && s.Auth.Apple.KID != "" {
|
||||
err := authenticator.AddAppleProvider(
|
||||
provider.AppleConfig{
|
||||
ClientID: s.Auth.Apple.CID,
|
||||
TeamID: s.Auth.Apple.TID,
|
||||
KeyID: s.Auth.Apple.KID,
|
||||
ResponseMode: "query", // default is form_post which wouldn't work here
|
||||
},
|
||||
provider.LoadApplePrivateKeyFromFile(s.Auth.Apple.PrivateKeyFilePath),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providersCount++
|
||||
}
|
||||
if s.Auth.Google.CID != "" && s.Auth.Google.CSEC != "" {
|
||||
authenticator.AddProvider("google", s.Auth.Google.CID, s.Auth.Google.CSEC)
|
||||
providersCount++
|
||||
@@ -1157,6 +1191,7 @@ func (s *ServerCommand) getAuthenticator(ds *service.DataStore, avas avatar.Stor
|
||||
Logger: log.Default(),
|
||||
RefreshCache: authRefreshCache,
|
||||
UseGravatar: true,
|
||||
AudSecrets: s.Admin.RPC.SecretPerSite,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1177,20 +1212,15 @@ func (s *ServerCommand) parseSameSite(ss string) http.SameSite {
|
||||
|
||||
// startTelegramAuthAndNotify initializes telegram notify and auth Telegram Bot listen loop.
|
||||
// Does nothing if telegram auth and notifications are disabled.
|
||||
// Doesn't return telegram bot username if user notifications are disabled, as that is the way frontend knows they are enabled.
|
||||
func (s *ServerCommand) startTelegramAuthAndNotify(ctx context.Context, telegramAuth providers.TGUpdatesReceiver) (tg *notify.Telegram, telegramBotUsername string) {
|
||||
func (s *ServerCommand) startTelegramAuthAndNotify(ctx context.Context, telegramAuth providers.TGUpdatesReceiver) (tg *notify.Telegram) {
|
||||
if !contains("telegram", s.Notify.Users) && !contains("telegram", s.Notify.Admins) && !s.Auth.Telegram {
|
||||
return nil, ""
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
if tg, err = s.makeTelegramNotify(); err != nil {
|
||||
log.Printf("[WARN] failed to make telegram notify service, %s", err)
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
if contains("telegram", s.Notify.Users) {
|
||||
telegramBotUsername = tg.GetBotUsername()
|
||||
return nil
|
||||
}
|
||||
|
||||
telegramReceivers := []providers.TGUpdatesReceiver{tg}
|
||||
@@ -1200,7 +1230,7 @@ func (s *ServerCommand) startTelegramAuthAndNotify(ctx context.Context, telegram
|
||||
// start bot messages receiver for both notify and auth services
|
||||
go providers.DispatchTelegramUpdates(ctx, tg, telegramReceivers, time.Second*5)
|
||||
|
||||
return tg, telegramBotUsername
|
||||
return tg
|
||||
}
|
||||
|
||||
// splitAtCommas split s at commas, ignoring commas in strings.
|
||||
|
||||
@@ -79,7 +79,7 @@ func TestServerApp_DevMode(t *testing.T) {
|
||||
waitForHTTPServerStart(port)
|
||||
|
||||
providers := app.restSrv.Authenticator.Providers()
|
||||
require.Equal(t, 9+1, len(providers), "extra auth provider")
|
||||
require.Equal(t, 10+1, len(providers), "extra auth provider")
|
||||
assert.Equal(t, "dev", providers[len(providers)-2].Name(), "dev auth provider")
|
||||
// send ping
|
||||
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/api/v1/ping", port))
|
||||
@@ -107,7 +107,7 @@ func TestServerApp_AnonMode(t *testing.T) {
|
||||
waitForHTTPServerStart(port)
|
||||
|
||||
providers := app.restSrv.Authenticator.Providers()
|
||||
require.Equal(t, 9+1, len(providers), "extra auth provider for anon")
|
||||
require.Equal(t, 10+1, len(providers), "extra auth provider for anon")
|
||||
assert.Equal(t, "anonymous", providers[len(providers)-1].Name(), "anon auth provider")
|
||||
|
||||
client := http.Client{Timeout: 10 * time.Second}
|
||||
@@ -290,7 +290,8 @@ func TestServerApp_WithRemote(t *testing.T) {
|
||||
port := chooseRandomUnusedPort()
|
||||
_, err := p.ParseArgs([]string{"--admin-passwd=password", "--cache.type=none",
|
||||
"--store.type=rpc", "--store.rpc.api=http://127.0.0.1",
|
||||
"--port=" + strconv.Itoa(port), "--admin.type=rpc", "--admin.rpc.api=http://127.0.0.1", "--avatar.fs.path=/tmp"})
|
||||
"--port=" + strconv.Itoa(port), "--avatar.fs.path=/tmp",
|
||||
"--admin.type=rpc", "--admin.rpc.secret_per_site", "--admin.rpc.api=http://127.0.0.1"})
|
||||
require.NoError(t, err)
|
||||
opts.Auth.Github.CSEC, opts.Auth.Github.CID = "csec", "cid"
|
||||
opts.BackupLocation, opts.Image.FS.Path = "/tmp", "/tmp"
|
||||
@@ -351,6 +352,7 @@ func TestServerApp_Failed(t *testing.T) {
|
||||
assert.EqualError(t, err, "invalid remark42 url demo.remark42.com")
|
||||
t.Log(err)
|
||||
|
||||
// wrong store type
|
||||
opts = ServerCommand{}
|
||||
opts.SetCommon(CommonOpts{RemarkURL: "https://demo.remark42.com", SharedSecret: "123456"})
|
||||
|
||||
@@ -374,6 +376,19 @@ func TestServerApp_Failed(t *testing.T) {
|
||||
"problem subscribing to channel remark42-cache on address wrong_address: "+
|
||||
"dial tcp: address wrong_address: missing port in address")
|
||||
t.Log(err)
|
||||
|
||||
// wrong apple private key type
|
||||
opts = ServerCommand{}
|
||||
opts.SetCommon(CommonOpts{RemarkURL: "https://demo.remark42.com", SharedSecret: "123456"})
|
||||
p = flags.NewParser(&opts, flags.Default)
|
||||
_, err = p.ParseArgs([]string{"--auth.apple.cid=123", "--auth.apple.tid=123",
|
||||
"--auth.apple.kid=123", "--auth.apple.private-key-filepath=testdata/apple-bad.p8"})
|
||||
assert.NoError(t, err)
|
||||
_, err = opts.newServerApp(context.Background())
|
||||
assert.EqualError(t, err,
|
||||
"failed to make authenticator: an AppleProvider creating failed: "+
|
||||
"provided private key is not ECDSA")
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
func TestServerApp_Shutdown(t *testing.T) {
|
||||
@@ -597,7 +612,7 @@ func TestServerAuthHooks(t *testing.T) {
|
||||
NotBefore: time.Now().Add(-1 * time.Minute).Unix(),
|
||||
},
|
||||
User: &token.User{
|
||||
ID: "dev",
|
||||
ID: "github_dev",
|
||||
Name: "developer one",
|
||||
},
|
||||
}
|
||||
@@ -636,14 +651,14 @@ func TestServerAuthHooks(t *testing.T) {
|
||||
require.NoError(t, resp.Body.Close())
|
||||
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode, "user without aud claim rejected, \n"+tkNoAud+"\n"+string(body))
|
||||
|
||||
// block user dev as admin
|
||||
// block user github_dev as admin
|
||||
req, err = http.NewRequest(http.MethodPut,
|
||||
fmt.Sprintf("http://localhost:%d/api/v1/admin/user/dev?site=remark&block=1&ttl=10d", port), http.NoBody)
|
||||
fmt.Sprintf("http://localhost:%d/api/v1/admin/user/github_dev?site=remark&block=1&ttl=10d", port), http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
req.SetBasicAuth("admin", "password")
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode, "user dev blocked")
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode, "user github_dev blocked")
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
@@ -758,6 +773,8 @@ func prepServerApp(t *testing.T, fn func(o ServerCommand) ServerCommand) (*serve
|
||||
cmd.Avatar.FS.Path, cmd.Avatar.Type, cmd.BackupLocation, cmd.Image.FS.Path = "/tmp/remark42_test", "fs", "/tmp/remark42_test", "/tmp/remark42_test"
|
||||
cmd.Store.Bolt.Path = fmt.Sprintf("/tmp/%d", cmd.Port)
|
||||
cmd.Store.Bolt.Timeout = 10 * time.Second
|
||||
cmd.Auth.Apple.CID, cmd.Auth.Apple.KID, cmd.Auth.Apple.TID = "cid", "kid", "tid"
|
||||
cmd.Auth.Apple.PrivateKeyFilePath = "testdata/apple.p8"
|
||||
cmd.Auth.Github.CSEC, cmd.Auth.Github.CID = "csec", "cid"
|
||||
cmd.Auth.Google.CSEC, cmd.Auth.Google.CID = "csec", "cid"
|
||||
cmd.Auth.Facebook.CSEC, cmd.Auth.Facebook.CID = "csec", "cid"
|
||||
@@ -804,8 +821,6 @@ func createAppFromCmd(t *testing.T, cmd ServerCommand) (*serverApp, context.Cont
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
app, err := cmd.newServerApp(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
return app, ctx, cancel
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKNwapOQ6rQJHetP
|
||||
HRlJBIh1OsOsUBiXb3rXXE3xpWAxAha0MH+UPRblOko+5T2JqIb+xKf9Vi3oTM3t
|
||||
KvffaOPtzKXZauscjq6NGzA3LgeiMy6q19pvkUUOlGYK6+Xfl+B7Xw6+hBMkQuGE
|
||||
nUS8nkpR5mK4ne7djIyfHFfMu4ptAgMBAAECgYA+s0PPtMq1osG9oi4xoxeAGikf
|
||||
JB3eMUptP+2DYW7mRibc+ueYKhB9lhcUoKhlQUhL8bUUFVZYakP8xD21thmQqnC4
|
||||
f63asad0ycteJMLb3r+z26LHuCyOdPg1pyLk3oQ32lVQHBCYathRMcVznxOG16VK
|
||||
I8BFfstJTaJu0lK/wQJBANYFGusBiZsJQ3utrQMVPpKmloO2++4q1v6ZR4puDQHx
|
||||
TjLjAIgrkYfwTJBLBRZxec0E7TmuVQ9uJ+wMu/+7zaUCQQDDf2xMnQqYknJoKGq+
|
||||
oAnyC66UqWC5xAnQS32mlnJ632JXA0pf9pb1SXAYExB1p9Dfqd3VAwQDwBsDDgP6
|
||||
HD8pAkEA0lscNQZC2TaGtKZk2hXkdcH1SKru/g3vWTkRHxfCAznJUaza1fx0wzdG
|
||||
GcES1Bdez0tbW4llI5By/skZc2eE3QJAFl6fOskBbGHde3Oce0F+wdZ6XIJhEgCP
|
||||
iukIcKZoZQzoiMJUoVRrA5gqnmaYDI5uRRl/y57zt6YksR3KcLUIuQJAd242M/WF
|
||||
6YAZat3q/wEeETeQq1wrooew+8lHl05/Nt0cCpV48RGEhJ83pzBm3mnwHf8lTBJH
|
||||
x6XroMXsmbnsEw==
|
||||
-----END PRIVATE KEY-----
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgGH2MylyZjjRdauTk
|
||||
xxXW6p8VSHqIeVRRKSJPg1xn6+KgCgYIKoZIzj0DAQehRANCAAS/mNzQ7aBbIBr3
|
||||
DiHiJGIDEzi6+q3mmyhH6ZWQWFdFei2qgdyM1V6qtRPVq+yHBNSBebbR4noE/IYO
|
||||
hMdWYrKn
|
||||
-----END PRIVATE KEY-----
|
||||
+3
-3
@@ -23,7 +23,8 @@ type Opts struct {
|
||||
CleanupCmd cmd.CleanupCommand `command:"cleanup"`
|
||||
RemapCmd cmd.RemapCommand `command:"remap"`
|
||||
|
||||
RemarkURL string `long:"url" env:"REMARK_URL" required:"true" description:"url to remark"`
|
||||
RemarkURL string `long:"url" env:"REMARK_URL" required:"true" description:"url to remark"`
|
||||
// SharedSecret is only used in server command, but defined for all commands for historical reasons
|
||||
SharedSecret string `long:"secret" env:"SECRET" required:"true" description:"the shared secret key used to sign JWT, should be a random, long, hard-to-guess string"`
|
||||
|
||||
Dbg bool `long:"dbg" env:"DEBUG" description:"debug mode"`
|
||||
@@ -56,9 +57,8 @@ func main() {
|
||||
if _, err := p.Parse(); err != nil {
|
||||
if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ func TestNative_ImportManyWithError(t *testing.T) {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(`{"version":1, "users":[], "posts":[]}` + "\n")
|
||||
for i := 0; i < 100; i++ {
|
||||
buf.WriteString(fmt.Sprintf(goodRec, i))
|
||||
fmt.Fprintf(buf, goodRec, i)
|
||||
}
|
||||
buf.WriteString("{}\n")
|
||||
buf.WriteString("{}\n")
|
||||
|
||||
@@ -143,6 +143,12 @@ func (s *Service) SubmitVerification(req VerificationRequest) {
|
||||
// Close queue channel and wait for completion
|
||||
func (s *Service) Close() {
|
||||
if s.queue != nil {
|
||||
// don't panic in case service is already closed
|
||||
select {
|
||||
case <-s.ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
log.Print("[DEBUG] close notifier")
|
||||
close(s.queue)
|
||||
close(s.verificationQueue)
|
||||
|
||||
@@ -21,6 +21,8 @@ func TestService_NoDestinations(t *testing.T) {
|
||||
s.Submit(Request{Comment: store.Comment{ID: "123"}})
|
||||
s.Submit(Request{Comment: store.Comment{ID: "123"}})
|
||||
s.Close()
|
||||
// second call should not result in panic
|
||||
s.Close()
|
||||
}
|
||||
|
||||
func TestService_WithDestinations(t *testing.T) {
|
||||
|
||||
@@ -743,9 +743,9 @@ func TestAdmin_DeleteMeRequestFailed(t *testing.T) {
|
||||
defer teardown()
|
||||
|
||||
c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "remark42",
|
||||
URL: "https://radio-t.com/blah"}, User: store.User{Name: "user1 name", ID: "user1"}}
|
||||
URL: "https://radio-t.com/blah"}, User: store.User{Name: "user1 name", ID: "provider1_user1"}}
|
||||
c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "remark42",
|
||||
URL: "https://radio-t.com/blah"}, User: store.User{Name: "user2", ID: "user2"}}
|
||||
URL: "https://radio-t.com/blah"}, User: store.User{Name: "user2", ID: "provider1_user2"}}
|
||||
|
||||
_, err := srv.DataService.Create(c1)
|
||||
assert.NoError(t, err)
|
||||
@@ -768,13 +768,13 @@ func TestAdmin_DeleteMeRequestFailed(t *testing.T) {
|
||||
SessionOnly: true,
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Audience: "remark42",
|
||||
Id: "1234567",
|
||||
Id: "provider1_1234567",
|
||||
Issuer: "remark42",
|
||||
NotBefore: time.Now().Add(-1 * time.Minute).Unix(),
|
||||
ExpiresAt: time.Now().Add(30 * time.Minute).Unix(),
|
||||
},
|
||||
User: &token.User{
|
||||
ID: "user1",
|
||||
ID: "provider1_user1",
|
||||
Attributes: map[string]interface{}{
|
||||
"delete_me": true,
|
||||
},
|
||||
|
||||
@@ -163,7 +163,7 @@ func (m *Migrator) remapCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "remap failed, bad given rules", rest.ErrDecode)
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
defer r.Body.Close() //nolint gosec // we don't care about response body
|
||||
|
||||
// start remap procedure with mapper
|
||||
go func() {
|
||||
|
||||
@@ -59,16 +59,16 @@ type Rest struct {
|
||||
Low int
|
||||
Critical int
|
||||
}
|
||||
UpdateLimiter float64
|
||||
EmailNotifications bool
|
||||
TelegramBotUsername string
|
||||
EmojiEnabled bool
|
||||
SimpleView bool
|
||||
ProxyCORS bool
|
||||
SendJWTHeader bool
|
||||
AllowedAncestors []string // sets Content-Security-Policy "frame-ancestors ..."
|
||||
SubscribersOnly bool
|
||||
DisableSignature bool // prevent signature from being added to headers
|
||||
UpdateLimiter float64
|
||||
EmailNotifications bool
|
||||
TelegramNotifications bool
|
||||
EmojiEnabled bool
|
||||
SimpleView bool
|
||||
ProxyCORS bool
|
||||
SendJWTHeader bool
|
||||
AllowedAncestors []string // sets Content-Security-Policy "frame-ancestors ..."
|
||||
SubscribersOnly bool
|
||||
DisableSignature bool // prevent signature from being added to headers
|
||||
|
||||
SSLConfig SSLConfig
|
||||
httpsServer *http.Server
|
||||
@@ -414,44 +414,44 @@ func (s *Rest) configCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
emails, _ := s.DataService.AdminStore.Email(siteID)
|
||||
|
||||
cnf := struct {
|
||||
Version string `json:"version"`
|
||||
EditDuration int `json:"edit_duration"`
|
||||
AdminEdit bool `json:"admin_edit"`
|
||||
MaxCommentSize int `json:"max_comment_size"`
|
||||
Admins []string `json:"admins"`
|
||||
AdminEmail string `json:"admin_email"`
|
||||
Auth []string `json:"auth_providers"`
|
||||
AnonVote bool `json:"anon_vote"`
|
||||
LowScore int `json:"low_score"`
|
||||
CriticalScore int `json:"critical_score"`
|
||||
PositiveScore bool `json:"positive_score"`
|
||||
ReadOnlyAge int `json:"readonly_age"`
|
||||
MaxImageSize int `json:"max_image_size"`
|
||||
EmailNotifications bool `json:"email_notifications"`
|
||||
TelegramBotUsername string `json:"telegram_bot_username"`
|
||||
EmojiEnabled bool `json:"emoji_enabled"`
|
||||
SimpleView bool `json:"simple_view"`
|
||||
SendJWTHeader bool `json:"send_jwt_header"`
|
||||
SubscribersOnly bool `json:"subscribers_only"`
|
||||
Version string `json:"version"`
|
||||
EditDuration int `json:"edit_duration"`
|
||||
AdminEdit bool `json:"admin_edit"`
|
||||
MaxCommentSize int `json:"max_comment_size"`
|
||||
Admins []string `json:"admins"`
|
||||
AdminEmail string `json:"admin_email"`
|
||||
Auth []string `json:"auth_providers"`
|
||||
AnonVote bool `json:"anon_vote"`
|
||||
LowScore int `json:"low_score"`
|
||||
CriticalScore int `json:"critical_score"`
|
||||
PositiveScore bool `json:"positive_score"`
|
||||
ReadOnlyAge int `json:"readonly_age"`
|
||||
MaxImageSize int `json:"max_image_size"`
|
||||
EmailNotifications bool `json:"email_notifications"`
|
||||
TelegramNotifications bool `json:"telegram_notifications"`
|
||||
EmojiEnabled bool `json:"emoji_enabled"`
|
||||
SimpleView bool `json:"simple_view"`
|
||||
SendJWTHeader bool `json:"send_jwt_header"`
|
||||
SubscribersOnly bool `json:"subscribers_only"`
|
||||
}{
|
||||
Version: s.Version,
|
||||
EditDuration: int(s.DataService.EditDuration.Seconds()),
|
||||
AdminEdit: s.DataService.AdminEdits,
|
||||
MaxCommentSize: s.DataService.MaxCommentSize,
|
||||
Admins: admins,
|
||||
AdminEmail: emails,
|
||||
LowScore: s.ScoreThresholds.Low,
|
||||
CriticalScore: s.ScoreThresholds.Critical,
|
||||
PositiveScore: s.DataService.PositiveScore,
|
||||
ReadOnlyAge: s.ReadOnlyAge,
|
||||
MaxImageSize: s.ImageService.MaxSize,
|
||||
EmailNotifications: s.EmailNotifications,
|
||||
TelegramBotUsername: s.TelegramBotUsername,
|
||||
EmojiEnabled: s.EmojiEnabled,
|
||||
AnonVote: s.AnonVote,
|
||||
SimpleView: s.SimpleView,
|
||||
SendJWTHeader: s.SendJWTHeader,
|
||||
SubscribersOnly: s.SubscribersOnly,
|
||||
Version: s.Version,
|
||||
EditDuration: int(s.DataService.EditDuration.Seconds()),
|
||||
AdminEdit: s.DataService.AdminEdits,
|
||||
MaxCommentSize: s.DataService.MaxCommentSize,
|
||||
Admins: admins,
|
||||
AdminEmail: emails,
|
||||
LowScore: s.ScoreThresholds.Low,
|
||||
CriticalScore: s.ScoreThresholds.Critical,
|
||||
PositiveScore: s.DataService.PositiveScore,
|
||||
ReadOnlyAge: s.ReadOnlyAge,
|
||||
MaxImageSize: s.ImageService.MaxSize,
|
||||
EmailNotifications: s.EmailNotifications,
|
||||
TelegramNotifications: s.TelegramNotifications,
|
||||
EmojiEnabled: s.EmojiEnabled,
|
||||
AnonVote: s.AnonVote,
|
||||
SimpleView: s.SimpleView,
|
||||
SendJWTHeader: s.SendJWTHeader,
|
||||
SubscribersOnly: s.SubscribersOnly,
|
||||
}
|
||||
|
||||
cnf.Auth = []string{}
|
||||
|
||||
@@ -90,11 +90,11 @@ func (s *private) previewCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
comment = s.commentFormatter.Format(comment)
|
||||
comment.Sanitize()
|
||||
|
||||
// check if images are valid
|
||||
for _, id := range s.imageService.ExtractPictures(comment.Text) {
|
||||
// check if images are valid, omit proxied images as they are lazy-loaded
|
||||
for _, id := range s.imageService.ExtractNonProxiedPictures(comment.Text) {
|
||||
err := s.imageService.ResetCleanupTimer(id)
|
||||
if err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't renew staged picture cleanup timer", rest.ErrImgNotFound)
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't load picture from the comment", rest.ErrImgNotFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -129,8 +129,8 @@ func (s *private) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
comment = s.commentFormatter.Format(comment)
|
||||
|
||||
// check if images are valid
|
||||
for _, id := range s.imageService.ExtractPictures(comment.Text) {
|
||||
// check if images are valid, omit proxied images as they are lazy-loaded
|
||||
for _, id := range s.imageService.ExtractNonProxiedPictures(comment.Text) {
|
||||
_, err := s.imageService.Load(id)
|
||||
if err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't load picture from the comment", rest.ErrImgNotFound)
|
||||
@@ -187,7 +187,7 @@ func (s *private) updateCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
}{}
|
||||
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &edit); err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment", rest.ErrDecode)
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't read comment details from body", rest.ErrDecode)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -307,28 +307,59 @@ func (s *private) getEmailCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// sendEmailConfirmationCtrl gets address and siteID from query, makes confirmation token and sends it to user.
|
||||
// GET /email/subscribe?site=siteID&address=someone@example.com
|
||||
// In case user is logged in with the same email, and auto_confirm is true, confirm it right away.
|
||||
// In case of quick confirmation, "updated" is set to true, otherwise - to false.
|
||||
// POST /email/subscribe with site and address in json body
|
||||
//
|
||||
//nolint:dupl // too hard to deduplicate that logic, as then it's tricky to use SendErrorJSON
|
||||
func (s *private) sendEmailConfirmationCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
user := rest.MustGetUserInfo(r)
|
||||
address := r.URL.Query().Get("address")
|
||||
siteID := r.URL.Query().Get("site")
|
||||
if address == "" {
|
||||
|
||||
subscribe := struct {
|
||||
Site string
|
||||
Address string
|
||||
autoConfirm bool
|
||||
}{autoConfirm: true}
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &subscribe); err != nil {
|
||||
if err != io.EOF {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't parse request body", rest.ErrDecode)
|
||||
return
|
||||
}
|
||||
// old behavior fallback, reading from the query params. Auto confirm is false in this case.
|
||||
subscribe.Address = r.URL.Query().Get("address")
|
||||
subscribe.Site = r.URL.Query().Get("site")
|
||||
subscribe.autoConfirm = false
|
||||
}
|
||||
|
||||
if subscribe.Address == "" {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest,
|
||||
fmt.Errorf("missing parameter"), "address parameter is required", rest.ErrInternal)
|
||||
return
|
||||
}
|
||||
existingAddress, err := s.dataService.GetUserEmail(siteID, user.ID)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] can't read email for %s, %v", user.ID, err)
|
||||
existingAddress, getErr := s.dataService.GetUserEmail(subscribe.Site, user.ID)
|
||||
if getErr != nil {
|
||||
log.Printf("[WARN] can't read email for %s, %v", user.ID, getErr)
|
||||
}
|
||||
if address == existingAddress {
|
||||
if subscribe.Address == existingAddress {
|
||||
rest.SendErrorJSON(w, r, http.StatusConflict,
|
||||
fmt.Errorf("already verified"), "email address is already verified for this user", rest.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
// in case the user logged in with the same email as they try to subscribe with, confirm it right away
|
||||
// this behavior is different from the previous one and is hidden behind the autoConfirm flag,
|
||||
// which is true for the new API, and false for the old one
|
||||
//
|
||||
// nolint:gosec // this is not used for security purposes
|
||||
if subscribe.autoConfirm &&
|
||||
strings.HasPrefix(user.ID, "email_") &&
|
||||
strings.TrimPrefix(user.ID, "email_") == token.HashID(sha1.New(), subscribe.Address) {
|
||||
s.setEmail(w, r, user.ID, subscribe.Site, subscribe.Address)
|
||||
return
|
||||
}
|
||||
|
||||
claims := token.Claims{
|
||||
Handshake: &token.Handshake{ID: user.ID + "::" + address},
|
||||
Handshake: &token.Handshake{ID: user.ID + "::" + subscribe.Address},
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Audience: r.URL.Query().Get("site"),
|
||||
ExpiresAt: time.Now().Add(30 * time.Minute).Unix(),
|
||||
@@ -345,14 +376,14 @@ func (s *private) sendEmailConfirmationCtrl(w http.ResponseWriter, r *http.Reque
|
||||
|
||||
s.notifyService.SubmitVerification(
|
||||
notify.VerificationRequest{
|
||||
SiteID: siteID,
|
||||
SiteID: subscribe.Site,
|
||||
User: user.Name,
|
||||
Email: address,
|
||||
Email: subscribe.Address,
|
||||
Token: tkn,
|
||||
},
|
||||
)
|
||||
|
||||
render.JSON(w, r, R.JSON{"user": user, "address": address})
|
||||
render.JSON(w, r, R.JSON{"user": user, "address": subscribe.Address, "updated": false})
|
||||
}
|
||||
|
||||
// telegramSubscribeCtrl generates and verifies telegram notification request
|
||||
@@ -399,7 +430,7 @@ func (s *private) telegramSubscribeCtrl(w http.ResponseWriter, r *http.Request)
|
||||
var address, siteID string
|
||||
address, siteID, err := s.telegramService.CheckToken(queryToken, user.ID)
|
||||
if err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "can't set telegram for user", rest.ErrInternal)
|
||||
rest.SendErrorJSON(w, r, http.StatusNotFound, err, "request is not verified yet", rest.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -416,17 +447,29 @@ func (s *private) telegramSubscribeCtrl(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// setConfirmedEmailCtrl uses provided token parameter (generated by sendEmailConfirmationCtrl) to set email and add it to user token
|
||||
// PUT /email/confirm?site=siteID&tkn=jwt
|
||||
// POST /email/confirm with site and token in json body
|
||||
func (s *private) setConfirmedEmailCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
tkn := r.URL.Query().Get("tkn")
|
||||
if tkn == "" {
|
||||
user := rest.MustGetUserInfo(r)
|
||||
|
||||
confirm := struct {
|
||||
Site string
|
||||
Token string
|
||||
}{}
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &confirm); err != nil {
|
||||
if err != io.EOF {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't parse request body", rest.ErrDecode)
|
||||
return
|
||||
}
|
||||
// old behavior fallback, reading from the query params
|
||||
confirm.Token = r.URL.Query().Get("tkn")
|
||||
confirm.Site = r.URL.Query().Get("site")
|
||||
}
|
||||
|
||||
if confirm.Token == "" {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, fmt.Errorf("missing parameter"), "token parameter is required", rest.ErrInternal)
|
||||
return
|
||||
}
|
||||
user := rest.MustGetUserInfo(r)
|
||||
siteID := r.URL.Query().Get("site")
|
||||
|
||||
confClaims, err := s.authenticator.TokenService().Parse(tkn)
|
||||
confClaims, err := s.authenticator.TokenService().Parse(confirm.Token)
|
||||
if err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusForbidden, err, "failed to verify confirmation token", rest.ErrInternal)
|
||||
return
|
||||
@@ -444,17 +487,20 @@ func (s *private) setConfirmedEmailCtrl(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
address := elems[1]
|
||||
s.setEmail(w, r, user.ID, confirm.Site, address)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] set email for user %s", user.ID)
|
||||
func (s *private) setEmail(w http.ResponseWriter, r *http.Request, userID, siteID, address string) {
|
||||
log.Printf("[DEBUG] set email for user %s", userID)
|
||||
|
||||
val, err := s.dataService.SetUserEmail(siteID, user.ID, address)
|
||||
val, err := s.dataService.SetUserEmail(siteID, userID, address)
|
||||
if err != nil {
|
||||
code := parseError(err, rest.ErrInternal)
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't set email for user", code)
|
||||
return
|
||||
}
|
||||
|
||||
// update User.Email from the token
|
||||
// update User.Email field
|
||||
claims, _, err := s.authenticator.TokenService().Get(r)
|
||||
if err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusForbidden, err, "failed to verify confirmation token", rest.ErrInternal)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -24,6 +25,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/umputun/remark42/backend/app/notify"
|
||||
"github.com/umputun/remark42/backend/app/rest/proxy"
|
||||
"github.com/umputun/remark42/backend/app/store"
|
||||
"github.com/umputun/remark42/backend/app/store/image"
|
||||
)
|
||||
@@ -69,7 +71,7 @@ func TestRest_CreateFilteredCode(t *testing.T) {
|
||||
|
||||
c := R.JSON{}
|
||||
err = json.Unmarshal(b, &c)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err, string(b))
|
||||
loc := c["locator"].(map[string]interface{})
|
||||
assert.Equal(t, "remark42", loc["site"])
|
||||
assert.Equal(t, "https://radio-t.com/blah1", loc["url"])
|
||||
@@ -79,6 +81,86 @@ func TestRest_CreateFilteredCode(t *testing.T) {
|
||||
assert.True(t, len(c["id"].(string)) > 8)
|
||||
}
|
||||
|
||||
// based on issue https://github.com/umputun/remark42/issues/1631
|
||||
func TestRest_CreateAndPreviewWithImage(t *testing.T) {
|
||||
ts, srv, teardown := startupT(t)
|
||||
ts.Close()
|
||||
defer teardown()
|
||||
|
||||
srv.ImageService.ProxyAPI = srv.RemarkURL + "/api/v1/img"
|
||||
srv.ImageProxy = &proxy.Image{
|
||||
HTTP2HTTPS: true,
|
||||
CacheExternal: true,
|
||||
RoutePath: "/api/v1/img",
|
||||
RemarkURL: srv.RemarkURL,
|
||||
ImageService: srv.ImageService,
|
||||
}
|
||||
srv.CommentFormatter = store.NewCommentFormatter(srv.ImageProxy)
|
||||
// need to recreate the server with new ImageProxy, otherwise old one will be used
|
||||
ts = httptest.NewServer(srv.routes())
|
||||
defer ts.Close()
|
||||
|
||||
var pngRead bool
|
||||
// server with the test PNG image
|
||||
pngServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, e := io.Copy(w, gopherPNG())
|
||||
assert.NoError(t, e)
|
||||
pngRead = true
|
||||
}))
|
||||
defer pngServer.Close()
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
resp, err := post(t, ts.URL+"/api/v1/comment",
|
||||
`{"text": "", "locator":{"url": "https://radio-t.com/blah1", "site": "remark42"}}`)
|
||||
assert.NoError(t, err)
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
require.Equal(t, http.StatusCreated, resp.StatusCode, string(b))
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
|
||||
c := R.JSON{}
|
||||
err = json.Unmarshal(b, &c)
|
||||
require.NoError(t, err, string(b))
|
||||
assert.NotContains(t, c["text"], pngServer.URL)
|
||||
assert.Contains(t, c["text"], srv.RemarkURL)
|
||||
loc := c["locator"].(map[string]interface{})
|
||||
assert.Equal(t, "remark42", loc["site"])
|
||||
assert.Equal(t, "https://radio-t.com/blah1", loc["url"])
|
||||
assert.True(t, len(c["id"].(string)) > 8)
|
||||
assert.Equal(t, false, pngRead, "original image is not yet accessed by server")
|
||||
})
|
||||
|
||||
t.Run("preview", func(t *testing.T) {
|
||||
resp, err := post(t, ts.URL+"/api/v1/preview",
|
||||
`{"text": "", "locator":{"url": "https://radio-t.com/blah1", "site": "remark42"}}`)
|
||||
assert.NoError(t, err)
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(b))
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
|
||||
assert.NotContains(t, string(b), pngServer.URL)
|
||||
assert.Contains(t, string(b), srv.RemarkURL)
|
||||
|
||||
assert.Equal(t, false, pngRead, "original image is not yet accessed by server")
|
||||
// retrieve the image from the cache
|
||||
imgURL := strings.Split(strings.Split(string(b), "src=\"")[1], "\"")[0]
|
||||
// replace srv.RemarkURL with ts.URL
|
||||
imgURL = strings.ReplaceAll(imgURL, srv.RemarkURL, ts.URL)
|
||||
resp, err = http.Get(imgURL)
|
||||
assert.NoError(t, err)
|
||||
b, err = io.ReadAll(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(b))
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
// compare image to original gopher png after decoding from base64
|
||||
assert.Equal(t, gopher, base64.StdEncoding.EncodeToString(b))
|
||||
|
||||
assert.Equal(t, true, pngRead, "original image accessed to be shown to user")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestRest_CreateOldPost(t *testing.T) {
|
||||
ts, srv, teardown := startupT(t)
|
||||
defer teardown()
|
||||
@@ -166,6 +248,25 @@ func TestRest_CreateWithRestrictedWord(t *testing.T) {
|
||||
assert.Equal(t, "invalid comment", c["details"])
|
||||
}
|
||||
|
||||
func TestRest_CreateRelativeURL(t *testing.T) {
|
||||
ts, _, teardown := startupT(t)
|
||||
defer teardown()
|
||||
|
||||
// check that it's not possible to click insert URL button and not alter the URL in it (which is `url` by default)
|
||||
relativeURLText := `{"text": "here is a link with relative URL: [google.com](url)", "locator":{"url": "https://radio-t.com/blah1", "site": "remark42"}}`
|
||||
resp, err := post(t, ts.URL+"/api/v1/comment", relativeURLText)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
c := R.JSON{}
|
||||
err = json.Unmarshal(b, &c)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "links should start with mailto:, http:// or https://", c["error"])
|
||||
assert.Equal(t, "invalid comment", c["details"])
|
||||
}
|
||||
|
||||
func TestRest_CreateRejected(t *testing.T) {
|
||||
ts, _, teardown := startupT(t)
|
||||
defer teardown()
|
||||
@@ -574,7 +675,7 @@ func TestRest_Vote(t *testing.T) {
|
||||
req, err := http.NewRequest(http.MethodPut,
|
||||
fmt.Sprintf("%s/api/v1/vote/%s?site=remark42&url=https://radio-t.com/blah&vote=%d", ts.URL, id1, val), http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
req.Header.Add("X-JWT", dev2Token)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
@@ -583,7 +684,7 @@ func TestRest_Vote(t *testing.T) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, vote(1), "first vote allowed")
|
||||
assert.Equal(t, http.StatusBadRequest, vote(1), "second vote rejected")
|
||||
body, code := getWithDevAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
body, code := getWithDev2Auth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
cr := store.Comment{}
|
||||
err := json.Unmarshal([]byte(body), &cr)
|
||||
@@ -594,7 +695,7 @@ func TestRest_Vote(t *testing.T) {
|
||||
assert.Equal(t, map[string]store.VotedIPInfo(nil), cr.VotedIPs, "hidden")
|
||||
|
||||
assert.Equal(t, http.StatusOK, vote(-1), "opposite vote allowed")
|
||||
body, code = getWithDevAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
body, code = getWithDev2Auth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
cr = store.Comment{}
|
||||
err = json.Unmarshal([]byte(body), &cr)
|
||||
@@ -603,7 +704,7 @@ func TestRest_Vote(t *testing.T) {
|
||||
assert.Equal(t, 0, cr.Vote)
|
||||
|
||||
assert.Equal(t, http.StatusOK, vote(-1), "opposite vote allowed one more time")
|
||||
body, code = getWithDevAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
body, code = getWithDev2Auth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
cr = store.Comment{}
|
||||
err = json.Unmarshal([]byte(body), &cr)
|
||||
@@ -612,7 +713,7 @@ func TestRest_Vote(t *testing.T) {
|
||||
assert.Equal(t, -1, cr.Vote)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, vote(-1), "dbl vote not allowed")
|
||||
body, code = getWithDevAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
body, code = getWithDev2Auth(t, fmt.Sprintf("%s/api/v1/id/%s?site=remark42&url=https://radio-t.com/blah", ts.URL, id1))
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
cr = store.Comment{}
|
||||
err = json.Unmarshal([]byte(body), &cr)
|
||||
@@ -709,7 +810,7 @@ func TestRest_EmailAndTelegram(t *testing.T) {
|
||||
|
||||
// issue good token
|
||||
claims := token.Claims{
|
||||
Handshake: &token.Handshake{ID: "dev::good@example.com"},
|
||||
Handshake: &token.Handshake{ID: "provider1_dev::good@example.com"},
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Audience: "remark42",
|
||||
ExpiresAt: time.Now().Add(10 * time.Minute).Unix(),
|
||||
@@ -728,19 +829,25 @@ func TestRest_EmailAndTelegram(t *testing.T) {
|
||||
responseCode int
|
||||
noAuth bool
|
||||
cookieEmail string
|
||||
body string
|
||||
}{
|
||||
{description: "issue delete request without auth", url: "/api/v1/email", method: http.MethodDelete, responseCode: http.StatusUnauthorized, noAuth: true},
|
||||
{description: "issue delete request without site_id", url: "/api/v1/email", method: http.MethodDelete, responseCode: http.StatusBadRequest},
|
||||
{description: "delete non-existent user email", url: "/api/v1/email?site=remark42", method: http.MethodDelete, responseCode: http.StatusOK},
|
||||
{description: "set user email, token not set", url: "/api/v1/email/confirm?site=remark42", method: http.MethodPost, responseCode: http.StatusBadRequest},
|
||||
{description: "send email confirmation without address", url: "/api/v1/email/subscribe?site=remark42", method: http.MethodPost, responseCode: http.StatusBadRequest},
|
||||
{description: "send email confirmation", url: "/api/v1/email/subscribe?site=remark42&address=good@example.com", method: http.MethodPost, responseCode: http.StatusOK},
|
||||
{description: "set user email, token is good", url: fmt.Sprintf("/api/v1/email/confirm?site=remark42&tkn=%s", goodToken), method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com"},
|
||||
{description: "set user email, token not set", url: "/api/v1/email/confirm", method: http.MethodPost, responseCode: http.StatusBadRequest, body: `{"site":"remark42"}`},
|
||||
{description: "set user email, token not set, old query param", url: "/api/v1/email/confirm?site=remark42", method: http.MethodPost, responseCode: http.StatusBadRequest},
|
||||
{description: "send email confirmation without address", url: "/api/v1/email/subscribe", method: http.MethodPost, responseCode: http.StatusBadRequest, body: `{"site":"remark42"}`},
|
||||
{description: "send email confirmation without address, old query param", url: "/api/v1/email/subscribe?site=remark42", method: http.MethodPost, responseCode: http.StatusBadRequest},
|
||||
{description: "send email confirmation", url: "/api/v1/email/subscribe", method: http.MethodPost, responseCode: http.StatusOK, body: `{"site":"remark42","address":"good@example.com"}`},
|
||||
{description: "send email confirmation, old query param", url: "/api/v1/email/subscribe?site=remark42&address=good@example.com", method: http.MethodPost, responseCode: http.StatusOK},
|
||||
{description: "set user email, token is good", url: "/api/v1/email/confirm", method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com", body: fmt.Sprintf(`{"site":"remark42","token":%q}`, goodToken)},
|
||||
{description: "set user email, token is good, old query param", url: fmt.Sprintf("/api/v1/email/confirm?site=remark42&tkn=%s", goodToken), method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com"},
|
||||
{description: "send confirmation with same address", url: "/api/v1/email/subscribe?site=remark42&address=good@example.com", method: http.MethodPost, responseCode: http.StatusConflict},
|
||||
{description: "get user email", url: "/api/v1/email?site=remark42", method: http.MethodGet, responseCode: http.StatusOK},
|
||||
{description: "delete user email", url: "/api/v1/email?site=remark42", method: http.MethodDelete, responseCode: http.StatusOK},
|
||||
{description: "send another confirmation", url: "/api/v1/email/subscribe?site=remark42&address=good@example.com", method: http.MethodPost, responseCode: http.StatusOK},
|
||||
{description: "set user email, token is good", url: fmt.Sprintf("/api/v1/email/confirm?site=remark42&tkn=%s", goodToken), method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com"},
|
||||
{description: "set user email, token is good", url: "/api/v1/email/confirm", method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com", body: fmt.Sprintf(`{"site":"remark42","token":%q}`, goodToken)},
|
||||
{description: "set user email, token is good, old query param", url: fmt.Sprintf("/api/v1/email/confirm?site=remark42&tkn=%s", goodToken), method: http.MethodPost, responseCode: http.StatusOK, cookieEmail: "good@example.com"},
|
||||
{description: "unsubscribe user, no token", url: "/email/unsubscribe.html?site=remark42", method: http.MethodPost, responseCode: http.StatusBadRequest},
|
||||
{description: "unsubscribe user, wrong token", url: "/email/unsubscribe.html?site=remark42&tkn=jwt", method: http.MethodGet, responseCode: http.StatusForbidden},
|
||||
{description: "unsubscribe user, good token", url: fmt.Sprintf("/email/unsubscribe.html?site=remark42&tkn=%s", goodToken), method: http.MethodPost, responseCode: http.StatusOK},
|
||||
@@ -761,7 +868,11 @@ func TestRest_EmailAndTelegram(t *testing.T) {
|
||||
for _, x := range testData {
|
||||
x := x
|
||||
t.Run(x.description, func(t *testing.T) {
|
||||
req, err := http.NewRequest(x.method, ts.URL+x.url, http.NoBody)
|
||||
reqBody := io.NopCloser(strings.NewReader(x.body))
|
||||
if x.body == "" {
|
||||
reqBody = http.NoBody
|
||||
}
|
||||
req, err := http.NewRequest(x.method, ts.URL+x.url, reqBody)
|
||||
require.NoError(t, err)
|
||||
if !x.noAuth {
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
@@ -798,7 +909,7 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
// create new comment from dev user
|
||||
req, err := http.NewRequest("POST", ts.URL+"/api/v1/comment", strings.NewReader(
|
||||
`{"text": "test 123",
|
||||
"user": {"name": "dev::good@example.com"},
|
||||
"user": {"name": "provider1_dev::good@example.com"},
|
||||
"locator":{"url": "https://radio-t.com/blah1",
|
||||
"site": "remark42"}}`))
|
||||
assert.NoError(t, err)
|
||||
@@ -837,7 +948,11 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
assert.Empty(t, mockDestination.Get()[1].Emails)
|
||||
|
||||
// send confirmation token for email
|
||||
req, err = http.NewRequest(http.MethodPost, ts.URL+"/api/v1/email/subscribe?site=remark42&address=good@example.com", http.NoBody)
|
||||
req, err = http.NewRequest(
|
||||
http.MethodPost,
|
||||
ts.URL+"/api/v1/email/subscribe",
|
||||
io.NopCloser(strings.NewReader(`{"site": "remark42", "address": "good@example.com"}`)),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
resp, err = client.Do(req)
|
||||
@@ -852,8 +967,31 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
assert.Equal(t, "good@example.com", mockDestination.GetVerify()[0].Email)
|
||||
verificationToken := mockDestination.GetVerify()[0].Token
|
||||
|
||||
// get user information to verify lack of the subscription
|
||||
req, err = http.NewRequest(
|
||||
http.MethodGet,
|
||||
ts.URL+"/api/v1/user?site=remark42",
|
||||
http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
var clearUser store.User
|
||||
err = json.Unmarshal(body, &clearUser)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "provider1_dev", EmailSubscription: false,
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, clearUser)
|
||||
|
||||
// verify email
|
||||
req, err = http.NewRequest(http.MethodPost, ts.URL+fmt.Sprintf("/api/v1/email/confirm?site=remark42&tkn=%s", verificationToken), http.NoBody)
|
||||
req, err = http.NewRequest(
|
||||
http.MethodPost,
|
||||
ts.URL+"/api/v1/email/confirm",
|
||||
io.NopCloser(strings.NewReader(fmt.Sprintf(`{"site": "remark42", "token": %q}`, verificationToken))),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
resp, err = client.Do(req)
|
||||
@@ -864,7 +1002,10 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
|
||||
// get user information to verify the subscription
|
||||
req, err = http.NewRequest(http.MethodGet, ts.URL+"/api/v1/user?site=remark42", http.NoBody)
|
||||
req, err = http.NewRequest(
|
||||
http.MethodGet,
|
||||
ts.URL+"/api/v1/user?site=remark42",
|
||||
http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", devToken)
|
||||
resp, err = client.Do(req)
|
||||
@@ -873,11 +1014,11 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
var user store.User
|
||||
err = json.Unmarshal(body, &user)
|
||||
var subscribedUser store.User
|
||||
err = json.Unmarshal(body, &subscribedUser)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "dev", EmailSubscription: true,
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, user)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "provider1_dev", EmailSubscription: true,
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, subscribedUser)
|
||||
|
||||
// create child comment from another user, email notification expected
|
||||
req, err = http.NewRequest("POST", ts.URL+"/api/v1/comment", strings.NewReader(fmt.Sprintf(
|
||||
@@ -928,6 +1069,80 @@ func TestRest_EmailNotification(t *testing.T) {
|
||||
time.Sleep(time.Millisecond * 30)
|
||||
require.Equal(t, 4, len(mockDestination.Get()))
|
||||
assert.Empty(t, mockDestination.Get()[3].Emails)
|
||||
|
||||
// confirm email via subscribe call with query params, old behavior, email notification is expected
|
||||
req, err = http.NewRequest(
|
||||
http.MethodPost,
|
||||
ts.URL+"/api/v1/email/subscribe?site=remark42&address=good@example.com",
|
||||
http.NoBody,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", emailUserToken)
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
// wait for mock notification Submit to kick off
|
||||
time.Sleep(time.Millisecond * 30)
|
||||
require.Equal(t, 2, len(mockDestination.GetVerify()), "verification email was sent")
|
||||
|
||||
// get email user information to verify there is no subscription yet
|
||||
req, err = http.NewRequest(
|
||||
http.MethodGet,
|
||||
ts.URL+"/api/v1/user?site=remark42",
|
||||
http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", emailUserToken)
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
var unsubscribedEmailUser store.User
|
||||
err = json.Unmarshal(body, &unsubscribedEmailUser)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "good@example.com test user", ID: "email_f5dfe9d2e6bd75fc74ea5fabf273b45b5baeb195", EmailSubscription: false,
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, unsubscribedEmailUser)
|
||||
|
||||
// confirm email via subscribe call, no email notification is expected
|
||||
req, err = http.NewRequest(
|
||||
http.MethodPost,
|
||||
ts.URL+"/api/v1/email/subscribe",
|
||||
io.NopCloser(strings.NewReader(`{"site": "remark42", "address": "good@example.com"}`)),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", emailUserToken)
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
// wait for mock notification Submit to kick off
|
||||
time.Sleep(time.Millisecond * 30)
|
||||
require.Equal(t, 2, len(mockDestination.GetVerify()), "no new verification email was sent")
|
||||
|
||||
// get email user information to verify the subscription happened without the confirmation call
|
||||
req, err = http.NewRequest(
|
||||
http.MethodGet,
|
||||
ts.URL+"/api/v1/user?site=remark42",
|
||||
http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", emailUserToken)
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, string(body))
|
||||
var subscribedEmailUser store.User
|
||||
err = json.Unmarshal(body, &subscribedEmailUser)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "good@example.com test user", ID: "email_f5dfe9d2e6bd75fc74ea5fabf273b45b5baeb195", EmailSubscription: true,
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, subscribedEmailUser)
|
||||
}
|
||||
|
||||
func TestRest_TelegramNotification(t *testing.T) {
|
||||
@@ -944,7 +1159,7 @@ func TestRest_TelegramNotification(t *testing.T) {
|
||||
// create new comment from dev user
|
||||
req, err := http.NewRequest("POST", ts.URL+"/api/v1/comment", strings.NewReader(
|
||||
`{"text": "test 123",
|
||||
"user": {"name": "dev::good@example.com"},
|
||||
"user": {"name": "provider1_dev::good@example.com"},
|
||||
"locator":{"url": "https://radio-t.com/blah1",
|
||||
"site": "remark42"}}`))
|
||||
assert.NoError(t, err)
|
||||
@@ -1023,8 +1238,8 @@ func TestRest_TelegramNotification(t *testing.T) {
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
require.Equal(t, http.StatusInternalServerError, resp.StatusCode, string(body))
|
||||
require.Equal(t, `{"code":0,"details":"can't set telegram for user","error":"not verified"}`+"\n", string(body))
|
||||
require.Equal(t, http.StatusNotFound, resp.StatusCode, string(body))
|
||||
require.Equal(t, `{"code":0,"details":"request is not verified yet","error":"not verified"}`+"\n", string(body))
|
||||
|
||||
mockTlgrm.notVerified = false
|
||||
|
||||
@@ -1072,7 +1287,7 @@ func TestRest_TelegramNotification(t *testing.T) {
|
||||
var user store.User
|
||||
err = json.Unmarshal(body, &user)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "dev",
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "provider1_dev",
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, user)
|
||||
|
||||
// create child comment from another user, telegram notification expected
|
||||
@@ -1131,7 +1346,7 @@ func TestRest_UserAllData(t *testing.T) {
|
||||
defer teardown()
|
||||
|
||||
// write 3 comments
|
||||
user := store.User{ID: "dev", Name: "user name 1"}
|
||||
user := store.User{ID: "provider1_dev", Name: "user name 1"}
|
||||
c1 := store.Comment{User: user, Text: "test test #1", Locator: store.Locator{SiteID: "remark42",
|
||||
URL: "https://radio-t.com/blah1"}, Timestamp: time.Date(2018, 5, 27, 1, 14, 10, 0, time.Local)}
|
||||
c2 := store.Comment{User: user, Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "remark42",
|
||||
@@ -1156,13 +1371,13 @@ func TestRest_UserAllData(t *testing.T) {
|
||||
require.Equal(t, "application/gzip", resp.Header.Get("Content-Type"))
|
||||
|
||||
ungzReader, err := gzip.NewReader(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
ungzBody, err := io.ReadAll(ungzReader)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
strUungzBody := string(ungzBody)
|
||||
assert.True(t, strings.HasPrefix(strUungzBody,
|
||||
`{"info": {"name":"developer one","id":"dev","picture":"http://example.com/pic.png","ip":"127.0.0.1","admin":false,"site_id":"remark42"}, "comments":[{`))
|
||||
`{"info": {"name":"developer one","id":"provider1_dev","picture":"http://example.com/pic.png","ip":"127.0.0.1","admin":false,"site_id":"remark42"}, "comments":[{`))
|
||||
assert.Equal(t, 3, strings.Count(strUungzBody, `"text":`), "3 comments inside")
|
||||
|
||||
parsed := struct {
|
||||
@@ -1172,7 +1387,7 @@ func TestRest_UserAllData(t *testing.T) {
|
||||
|
||||
err = json.Unmarshal(ungzBody, &parsed)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "dev",
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "provider1_dev",
|
||||
Picture: "http://example.com/pic.png", IP: "127.0.0.1", SiteID: "remark42"}, parsed.Info)
|
||||
assert.Equal(t, 3, len(parsed.Comments))
|
||||
|
||||
@@ -1188,7 +1403,7 @@ func TestRest_UserAllDataManyComments(t *testing.T) {
|
||||
ts, srv, teardown := startupT(t)
|
||||
defer teardown()
|
||||
|
||||
user := store.User{ID: "dev", Name: "user name 1"}
|
||||
user := store.User{ID: "provider1_dev", Name: "user name 1"}
|
||||
c := store.Comment{User: user, Text: "test test #1", Locator: store.Locator{SiteID: "remark42",
|
||||
URL: "https://radio-t.com/blah1"}, Timestamp: time.Date(2018, 5, 27, 1, 14, 10, 0, time.Local)}
|
||||
|
||||
@@ -1215,7 +1430,7 @@ func TestRest_UserAllDataManyComments(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
strUngzBody := string(ungzBody)
|
||||
assert.True(t, strings.HasPrefix(strUngzBody,
|
||||
`{"info": {"name":"developer one","id":"dev","picture":"http://example.com/pic.png","ip":"127.0.0.1","admin":false,"site_id":"remark42"}, "comments":[{`))
|
||||
`{"info": {"name":"developer one","id":"provider1_dev","picture":"http://example.com/pic.png","ip":"127.0.0.1","admin":false,"site_id":"remark42"}, "comments":[{`))
|
||||
assert.Equal(t, 51, strings.Count(strUngzBody, `"text":`), "51 comments inside")
|
||||
}
|
||||
|
||||
@@ -1239,12 +1454,12 @@ func TestRest_DeleteMe(t *testing.T) {
|
||||
err = json.Unmarshal(body, &m)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "remark42", m["site"])
|
||||
assert.Equal(t, "dev", m["user_id"])
|
||||
assert.Equal(t, "provider1_dev", m["user_id"])
|
||||
|
||||
tkn := m["token"]
|
||||
claims, err := srv.Authenticator.TokenService().Parse(tkn)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "dev", claims.User.ID)
|
||||
assert.Equal(t, "provider1_dev", claims.User.ID)
|
||||
assert.Equal(t, "https://demo.remark42.com/web/deleteme.html?token="+tkn, m["link"])
|
||||
|
||||
req, err = http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/v1/deleteme?site=remark42", ts.URL), http.NoBody)
|
||||
|
||||
@@ -76,8 +76,8 @@ func TestRest_Preview(t *testing.T) {
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
assert.Contains(t,
|
||||
string(b),
|
||||
"{\"code\":20,\"details\":\"can't renew staged picture cleanup timer\","+
|
||||
"\"error\":\"can't get image stats for dev_user/bad_picture: stat",
|
||||
`{"code":20,"details":"can't load picture from the comment",`+
|
||||
`"error":"can't get image stats for dev_user/bad_picture: stat`,
|
||||
)
|
||||
assert.Contains(t,
|
||||
string(b),
|
||||
@@ -97,8 +97,8 @@ func TestRest_PreviewWithWrongImage(t *testing.T) {
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
assert.Contains(t,
|
||||
string(b),
|
||||
"{\"code\":20,\"details\":\"can't renew staged picture cleanup timer\","+
|
||||
"\"error\":\"can't get image stats for dev_user/bad_picture: stat ",
|
||||
`{"code":20,"details":"can't load picture from the comment",`+
|
||||
`"error":"can't get image stats for dev_user/bad_picture: stat `,
|
||||
)
|
||||
assert.Contains(t,
|
||||
string(b),
|
||||
@@ -325,8 +325,8 @@ func TestRest_FindUserView(t *testing.T) {
|
||||
require.Equal(t, 2, len(comments.Comments), "should have 2 comments")
|
||||
assert.Equal(t, id1, comments.Comments[0].ID)
|
||||
assert.Equal(t, id2, comments.Comments[1].ID)
|
||||
assert.Equal(t, "dev", comments.Comments[0].User.ID)
|
||||
assert.Equal(t, "dev", comments.Comments[1].User.ID)
|
||||
assert.Equal(t, "provider1_dev", comments.Comments[0].User.ID)
|
||||
assert.Equal(t, "provider1_dev", comments.Comments[1].User.ID)
|
||||
assert.Equal(t, "", comments.Comments[0].Text)
|
||||
assert.Equal(t, "", comments.Comments[1].Text)
|
||||
|
||||
@@ -440,7 +440,7 @@ func TestRest_FindUserComments(t *testing.T) {
|
||||
assert.Equal(t, http.StatusOK, code, "noting for user blah")
|
||||
assert.Equal(t, `{"comments":[],"count":0}`+"\n", comments)
|
||||
{
|
||||
res, code := get(t, ts.URL+"/api/v1/comments?site=remark42&user=dev")
|
||||
res, code := get(t, ts.URL+"/api/v1/comments?site=remark42&user=provider1_dev")
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
|
||||
resp := struct {
|
||||
@@ -459,7 +459,7 @@ func TestRest_FindUserComments(t *testing.T) {
|
||||
}
|
||||
|
||||
{
|
||||
res, code := get(t, ts.URL+"/api/v1/comments?site=remark42&user=dev&skip=1&limit=2")
|
||||
res, code := get(t, ts.URL+"/api/v1/comments?site=remark42&user=provider1_dev&skip=1&limit=2")
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
|
||||
resp := struct {
|
||||
@@ -486,7 +486,7 @@ func TestRest_UserInfo(t *testing.T) {
|
||||
user := store.User{}
|
||||
err := json.Unmarshal([]byte(body), &user)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "dev", Picture: "http://example.com/pic.png",
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "provider1_dev", Picture: "http://example.com/pic.png",
|
||||
IP: "127.0.0.1", SiteID: "remark42"}, user)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/go-pkgz/auth"
|
||||
"github.com/go-pkgz/auth/avatar"
|
||||
"github.com/go-pkgz/auth/provider"
|
||||
"github.com/go-pkgz/auth/token"
|
||||
cache "github.com/go-pkgz/lcw"
|
||||
R "github.com/go-pkgz/rest"
|
||||
@@ -37,11 +38,18 @@ import (
|
||||
"github.com/umputun/remark42/backend/app/store/service"
|
||||
)
|
||||
|
||||
var devToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6Mzc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjE4ODQyMjIsInVzZXIiOnsibmFtZSI6ImRldmVsb3BlciBvbmUiLCJpZCI6ImRldiIsInBpY3R1cmUiOiJodHRwOi8vZXhhbXBsZS5jb20vcGljLnBuZyIsImlwIjoiMTI3LjAuMC4xIiwiZW1haWwiOiJtZUBleGFtcGxlLmNvbSJ9fQ.aKUAXiZxXypgV7m1wEOgUcyPOvUDXHDi3A06YWKbcLg`
|
||||
// To generate a token, enter one of the tokens here into https://jwt.io, change the secret to one you're using in your test
|
||||
// ("secret" in case of startupT), and alter the fields you want to be changed.
|
||||
|
||||
var devToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6Mzc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjE4ODQyMjIsInVzZXIiOnsibmFtZSI6ImRldmVsb3BlciBvbmUiLCJpZCI6InByb3ZpZGVyMV9kZXYiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20ifX0.dirTS_ahSF6375sdO2iodm2K2UmRTzQNQMFiHuTQCVs`
|
||||
|
||||
var dev2Token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6Mzc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjE4ODQyMjIsInVzZXIiOnsibmFtZSI6ImRldmVsb3BlciBvbmUiLCJpZCI6InByb3ZpZGVyMV9kZXYyIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIn19.qsR_PupfjIq7uw0eAuyGV8nsUoMx9v541c9olnRInRQ`
|
||||
|
||||
var anonToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6Mzc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjE4ODQyMjIsInVzZXIiOnsibmFtZSI6ImFub255bW91cyB0ZXN0IHVzZXIiLCJpZCI6ImFub255bW91c190ZXN0X3VzZXIiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoiYW5vbkBleGFtcGxlLmNvbSJ9fQ.gAae2WMxZNZE5ebVboptPEyQ7Nk6EQxciNnGJ_mPOuU`
|
||||
|
||||
var devTokenBadAud = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0Ml9iYWQiLCJleHAiOjM3ODkxOTE4MjIsImp0aSI6InJhbmRvbSBpZCIsImlzcyI6InJlbWFyazQyIiwibmJmIjoxNTIxODg0MjIyLCJ1c2VyIjp7Im5hbWUiOiJkZXZlbG9wZXIgb25lIiwiaWQiOiJkZXYiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20ifX0.FuTTocVtcxr4VjpfIICvU2yOb3su28VkDzj94H9Q3xY`
|
||||
var emailUserToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6Mzc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjE4ODQyMjIsInVzZXIiOnsibmFtZSI6Imdvb2RAZXhhbXBsZS5jb20gdGVzdCB1c2VyIiwiaWQiOiJlbWFpbF9mNWRmZTlkMmU2YmQ3NWZjNzRlYTVmYWJmMjczYjQ1YjViYWViMTk1IiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Imdvb2RAZXhhbXBsZS5jb20ifX0.vH2HN1JpuXL8okTJq1A-zGHQ-l2ILcwxvDDEmu2zwks`
|
||||
|
||||
var devTokenBadAud = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcms0Ml9iYWQiLCJleHAiOjM3ODkxOTE4MjIsImp0aSI6InJhbmRvbSBpZCIsImlzcyI6InJlbWFyazQyIiwibmJmIjoxNTIxODg0MjIyLCJ1c2VyIjp7Im5hbWUiOiJkZXZlbG9wZXIgb25lIiwiaWQiOiJwcm92aWRlcjFfZGV2IiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIn19.X-lvnHvBz6VfEbVV4f-bjcZuLY5pYtvEansk_TQMrX8`
|
||||
|
||||
var adminUmputunToken = `eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJyZW1hcms0MiIsImV4cCI6MTk1NDU5Nzk4MCwianRpIjoiOTdhMmUwYWM0ZGM3ZDVmNjkyNmQ1ZTg2MjBhY2VmOWE0MGMwIiwiaWF0IjoxNDU0NTk3NjgwLCJpc3MiOiJyZW1hcms0MiIsInVzZXIiOnsibmFtZSI6IlVtcHV0dW4iLCJpZCI6ImdpdGh1Yl9lZjBmNzA2YTciLCJwaWN0dXJlIjoiaHR0cHM6Ly9yZW1hcms0Mi5yYWRpby10LmNvbS9hcGkvdjEvYXZhdGFyL2NiNDJmZjQ5M2FkZTY5NmQ4OGEzYTU5MGYxMzZhZTllMzRkZTdjMWIuaW1hZ2UiLCJhdHRycyI6eyJhZG1pbiI6dHJ1ZSwiYmxvY2tlZCI6ZmFsc2V9fX0.dZiOjWHguo9f42XCMooMcv4EmYFzifl_-LEvPZHCtks`
|
||||
|
||||
@@ -296,7 +304,7 @@ func TestRest_cacheControl(t *testing.T) {
|
||||
for i, tt := range tbl {
|
||||
tt := tt
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", tt.url, nil)
|
||||
req := httptest.NewRequest("GET", tt.url, http.NoBody)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h := cacheControl(tt.exp, tt.version)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
|
||||
@@ -324,7 +332,7 @@ func TestRest_frameAncestors(t *testing.T) {
|
||||
for i, tt := range tbl {
|
||||
tt := tt
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "http://example.com", nil)
|
||||
req := httptest.NewRequest("GET", "http://example.com", http.NoBody)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h := frameAncestors(tt.hosts)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
|
||||
@@ -358,7 +366,7 @@ func TestRest_subscribersOnly(t *testing.T) {
|
||||
for i, tt := range tbl {
|
||||
tt := tt
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "http://example.com", nil)
|
||||
req := httptest.NewRequest("GET", "http://example.com", http.NoBody)
|
||||
if tt.setUser {
|
||||
req = token.SetUserInfo(req, tt.user)
|
||||
}
|
||||
@@ -484,6 +492,14 @@ func startupT(t *testing.T, srvHook ...func(srv *Rest)) (ts *httptest.Server, sr
|
||||
}
|
||||
srv.ScoreThresholds.Low, srv.ScoreThresholds.Critical = -5, -10
|
||||
|
||||
// add some providers. Needed because we don't allow users with unlisted providers to authenticate
|
||||
providers := []string{"provider1", "anonymous", "github", "email"}
|
||||
for _, p := range providers {
|
||||
srv.Authenticator.AddDirectProvider(p, provider.CredCheckerFunc(func(user, password string) (ok bool, err error) {
|
||||
return true, nil
|
||||
}))
|
||||
}
|
||||
|
||||
for _, h := range srvHook {
|
||||
h(srv)
|
||||
}
|
||||
@@ -547,6 +563,20 @@ func getWithDevAuth(t *testing.T, url string) (body string, code int) {
|
||||
return string(b), r.StatusCode
|
||||
}
|
||||
|
||||
func getWithDev2Auth(t *testing.T, url string) (body string, code int) {
|
||||
client := &http.Client{Timeout: 5 * time.Second}
|
||||
defer client.CloseIdleConnections()
|
||||
req, err := http.NewRequest("GET", url, http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Add("X-JWT", dev2Token)
|
||||
r, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
b, err := io.ReadAll(r.Body)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, r.Body.Close())
|
||||
return string(b), r.StatusCode
|
||||
}
|
||||
|
||||
func getWithAdminAuth(t *testing.T, url string) (response string, statusCode int) {
|
||||
client := &http.Client{Timeout: 5 * time.Second}
|
||||
defer client.CloseIdleConnections()
|
||||
|
||||
@@ -159,7 +159,7 @@ func (p Image) downloadImage(ctx context.Context, imgURL string) ([]byte, error)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't download image %s: %w", imgURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer resp.Body.Close() //nolint gosec // we don't care about response body
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("got unsuccessful response status %d while fetching %s", resp.StatusCode, imgURL)
|
||||
|
||||
@@ -118,9 +118,11 @@ func (c *Comment) SetDeleted(mode DeleteMode) {
|
||||
func (c *Comment) Sanitize() {
|
||||
p := bluemonday.UGCPolicy()
|
||||
p.AllowAttrs("class").Matching(regexp.MustCompile("^chroma$")).OnElements("pre")
|
||||
// special case for embedding the quotes from Twitter
|
||||
p.AllowAttrs("class").Matching(regexp.MustCompile("^twitter-tweet$")).OnElements("blockquote")
|
||||
// this is list of <span> tag classes which could be produced by chroma code renderer
|
||||
// source: https://github.com/alecthomas/chroma/blob/cc2dd5b/types.go#L211-L307
|
||||
const codeSpanClassRegex = "^(bg|chroma|line|ln|lnt|hl|lntable|lntd|cl|w|err|x|k|kc" +
|
||||
// source: https://github.com/alecthomas/chroma/blob/c263f6f/types.go#L209-L306
|
||||
const codeSpanClassRegex = "^(bg|chroma|line|ln|lnt|hl|lntable|lntd|lnlinks|cl|w|err|x|k|kc" +
|
||||
"|kd|kn|kp|kr|kt|n|na|nb|bp|nc|no|nd|ni|ne|nf|fm|py|nl|nn|nx|nt|nv|vc|vg" +
|
||||
"|vi|vm|l|ld|s|sa|sb|sc|dl|sd|s2|se|sh|si|sx|sr|s1|ss|m|mb|mf|mh|mi|il" +
|
||||
"|mo|o|ow|p|c|ch|cm|cp|cpf|c1|cs|g|gd|ge|gr|gh|gi|go|gp|gs|gu|gt|gl)$"
|
||||
@@ -144,7 +146,7 @@ func (c *Comment) Snippet(limit int) string {
|
||||
if size < limit {
|
||||
return cleanText
|
||||
}
|
||||
snippet := []rune(cleanText)[:size]
|
||||
snippet := []rune(cleanText)[:limit]
|
||||
// go back in snippet and found the first space
|
||||
for i := len(snippet) - 1; i >= 0; i-- {
|
||||
if snippet[i] == ' ' {
|
||||
@@ -152,6 +154,10 @@ func (c *Comment) Snippet(limit int) string {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Don't add a space if comment is just a one single word which has been truncated.
|
||||
if len(snippet) == limit {
|
||||
return string(snippet) + "..."
|
||||
}
|
||||
return string(snippet) + " ..."
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,10 @@ func TestComment_Sanitize(t *testing.T) {
|
||||
inp: Comment{Text: "blah blah", PostTitle: "<script>alert()</script>something"},
|
||||
out: Comment{Text: "blah blah", PostTitle: "something"},
|
||||
},
|
||||
{
|
||||
inp: Comment{Text: `<blockquote class="twitter-tweet"><p lang="es" dir="ltr">Silicon iMac Concept<a href="https://t.co/7ga95QxVXn">https://t.co/7ga95QxVXn</a> by <a href="https://twitter.com/marcsheep?ref_src=twsrc%5Etfw">@marcsheep</a> <a href="https://t.co/ULnVpG8w55">pic.twitter.com/ULnVpG8w55</a></p>— Andreas Storm (@avstorm) <a href="https://twitter.com/avstorm/status/1325693387798933504?ref_src=twsrc%5Etfw">November 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>`, PostTitle: "Twitter quote"},
|
||||
out: Comment{Text: `<blockquote class="twitter-tweet"><p lang="es" dir="ltr">Silicon iMac Concept<a href="https://t.co/7ga95QxVXn" rel="nofollow">https://t.co/7ga95QxVXn</a> by <a href="https://twitter.com/marcsheep?ref_src=twsrc%5Etfw" rel="nofollow">@marcsheep</a> <a href="https://t.co/ULnVpG8w55" rel="nofollow">pic.twitter.com/ULnVpG8w55</a></p>— Andreas Storm (@avstorm) <a href="https://twitter.com/avstorm/status/1325693387798933504?ref_src=twsrc%5Etfw" rel="nofollow">November 9, 2020</a></blockquote> `, PostTitle: "Twitter quote"},
|
||||
},
|
||||
}
|
||||
|
||||
for n, tt := range tbl {
|
||||
@@ -192,8 +196,8 @@ func TestComment_Snippet(t *testing.T) {
|
||||
{0, "", ""},
|
||||
{-1, "test\nblah", "test blah"},
|
||||
{5, "test\nblah", "test ..."},
|
||||
{5, "xyz12345 xxx", "xyz12345 ..."},
|
||||
{10, "xyz12345 xxx\ntest 123456", "xyz12345 xxx test ..."},
|
||||
{5, "xyz12345 xxx", "xyz12..."},
|
||||
{10, "xyz12345 xxx\ntest 123456", "xyz12345 ..."},
|
||||
}
|
||||
|
||||
for i, tt := range tbl {
|
||||
@@ -259,7 +263,7 @@ func TestComment_sanitizeText(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"<a href=javascript:alert(document.domain)//>xxx</a>",
|
||||
"<a/>xxx</a>",
|
||||
"xxx</a>",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -911,6 +911,13 @@ func TestBoltDB_NewFailed(t *testing.T) {
|
||||
assert.EqualError(t, err, "failed to make boltdb for /tmp/no-such-place/tmp.db: open /tmp/no-such-place/tmp.db: no such file or directory")
|
||||
}
|
||||
|
||||
func TestBoltDB_DoubleClose(t *testing.T) {
|
||||
var b, teardown = prep(t)
|
||||
defer teardown()
|
||||
assert.NoError(t, b.Close())
|
||||
assert.NoError(t, b.Close(), "second call should not result in panic or errors")
|
||||
}
|
||||
|
||||
// makes new boltdb, put two records
|
||||
func prep(t *testing.T) (b *BoltDB, teardown func()) {
|
||||
_ = os.Remove(testDB)
|
||||
|
||||
@@ -186,11 +186,17 @@ func TestRemote_Delete(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemote_Close(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"store.close","id":1}`, `{}`)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(body), "{\"method\":\"store.close\",\"id\":")
|
||||
t.Logf("req: %s", string(body))
|
||||
_, _ = fmt.Fprint(w, "{}")
|
||||
}))
|
||||
defer ts.Close()
|
||||
c := RPC{Client: jrpc.Client{API: ts.URL, Client: http.Client{}}}
|
||||
err := c.Close()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, c.Close())
|
||||
assert.NoError(t, c.Close(), "second call should not result in panic or errors")
|
||||
}
|
||||
|
||||
func testServer(t *testing.T, req, resp string) *httptest.Server {
|
||||
|
||||
@@ -42,17 +42,8 @@ func (f *CommentFormatter) Format(c Comment) Comment {
|
||||
|
||||
// FormatText converts text with markdown processor, applies external converters and shortens links
|
||||
func (f *CommentFormatter) FormatText(txt string) (res string) {
|
||||
mdExt := bf.NoIntraEmphasis | bf.Tables | bf.FencedCode |
|
||||
bf.Strikethrough | bf.SpaceHeadings | bf.HardLineBreak |
|
||||
bf.BackslashLineBreak | bf.Autolink
|
||||
|
||||
rend := bf.NewHTMLRenderer(bf.HTMLRendererParameters{
|
||||
Flags: bf.Smartypants | bf.SmartypantsFractions | bf.SmartypantsDashes | bf.SmartypantsAngledQuotes,
|
||||
})
|
||||
|
||||
extRend := bfchroma.NewRenderer(bfchroma.Extend(rend), bfchroma.ChromaOptions(html.WithClasses(true)))
|
||||
|
||||
res = string(bf.Run([]byte(txt), bf.WithExtensions(mdExt), bf.WithRenderer(extRend)))
|
||||
mdExt, rend := GetMdExtensionsAndRenderer()
|
||||
res = string(bf.Run([]byte(txt), bf.WithExtensions(mdExt), bf.WithRenderer(rend)))
|
||||
res = f.unEscape(res)
|
||||
|
||||
for _, conv := range f.converters {
|
||||
@@ -126,3 +117,18 @@ func (f *CommentFormatter) lazyImage(commentHTML string) (resHTML string) {
|
||||
}
|
||||
return resHTML
|
||||
}
|
||||
|
||||
// GetMdExtensionsAndRenderer returns blackfriday extensions and renderer used for rendering markdown
|
||||
// within store module.
|
||||
func GetMdExtensionsAndRenderer() (bf.Extensions, *bfchroma.Renderer) {
|
||||
mdExt := bf.NoIntraEmphasis | bf.Tables | bf.FencedCode |
|
||||
bf.Strikethrough | bf.SpaceHeadings | bf.HardLineBreak |
|
||||
bf.BackslashLineBreak | bf.Autolink
|
||||
|
||||
rend := bf.NewHTMLRenderer(bf.HTMLRendererParameters{
|
||||
Flags: bf.Smartypants | bf.SmartypantsFractions | bf.SmartypantsDashes | bf.SmartypantsAngledQuotes,
|
||||
})
|
||||
|
||||
extRend := bfchroma.NewRenderer(bfchroma.Extend(rend), bfchroma.ChromaOptions(html.WithClasses(true)))
|
||||
return mdExt, extRend
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ func TestFormatter_FormatText(t *testing.T) {
|
||||
},
|
||||
{"— not translated #354", "<p>— not translated #354</p>\n!converted", "mdash"},
|
||||
{"smth\n```go\nfunc main(aa string) int {return 0}\n```", `<p>smth</p>
|
||||
<pre tabindex="0" class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(</span><span class="nx">aa</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">int</span> <span class="p">{</span><span class="k">return</span> <span class="mi">0</span><span class="p">}</span>
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(</span><span class="nx">aa</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">int</span> <span class="p">{</span><span class="k">return</span> <span class="mi">0</span><span class="p">}</span>
|
||||
</span></span></code></pre>!converted`, "code with language"},
|
||||
{"```\ntest_code\n```", `<pre tabindex="0" class="chroma"><code><span class="line"><span class="cl">test_code
|
||||
{"```\ntest_code\n```", `<pre class="chroma"><code><span class="line"><span class="cl">test_code
|
||||
</span></span></code></pre>!converted`, "code without language"},
|
||||
}
|
||||
f := NewCommentFormatter(mockConverter{})
|
||||
|
||||
@@ -88,8 +88,8 @@ func NewService(s Store, p ServiceParams) *Service {
|
||||
return &Service{ServiceParams: p, store: s}
|
||||
}
|
||||
|
||||
// SubmitAndCommit multiple ids immediately
|
||||
func (s *Service) SubmitAndCommit(idsFn func() []string) error {
|
||||
// Commit multiple ids immediately
|
||||
func (s *Service) Commit(idsFn func() []string) error {
|
||||
errs := new(multierror.Error)
|
||||
for _, id := range idsFn() {
|
||||
err := s.store.Commit(id)
|
||||
@@ -117,7 +117,7 @@ func (s *Service) Submit(idsFn func() []string) {
|
||||
for atomic.LoadInt32(&s.term) == 0 && time.Since(req.TS) <= s.EditDuration {
|
||||
time.Sleep(time.Millisecond * 10) // small sleep to relive busy wait but keep reactive for term (close)
|
||||
}
|
||||
err := s.SubmitAndCommit(req.idsFn)
|
||||
err := s.Commit(req.idsFn)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] image commit error %v", err)
|
||||
}
|
||||
@@ -141,39 +141,14 @@ func (s *Service) Submit(idsFn func() []string) {
|
||||
|
||||
// ExtractPictures gets list of images from the doc html and convert from urls to ids, i.e. user/pic.png
|
||||
func (s *Service) ExtractPictures(commentHTML string) (ids []string) {
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(commentHTML))
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] can't parse commentHTML to parse images: %q, error: %v", commentHTML, err)
|
||||
return nil
|
||||
}
|
||||
doc.Find("img").Each(func(i int, sl *goquery.Selection) {
|
||||
if im, ok := sl.Attr("src"); ok {
|
||||
if strings.Contains(im, s.ImageAPI) {
|
||||
elems := strings.Split(im, "/")
|
||||
if len(elems) >= 2 {
|
||||
id := elems[len(elems)-2] + "/" + elems[len(elems)-1]
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
if strings.Contains(im, s.ProxyAPI) {
|
||||
proxiedURL, err := url.Parse(im)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
imgURL, err := base64.URLEncoding.DecodeString(proxiedURL.Query().Get("src"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
imgID, err := CachedImgID(string(imgURL))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ids = append(ids, imgID)
|
||||
}
|
||||
}
|
||||
})
|
||||
return s.extractImageIDs(commentHTML, true)
|
||||
}
|
||||
|
||||
return ids
|
||||
// ExtractNonProxiedPictures gets list of non-proxied images from the doc html and convert from urls to ids, i.e. user/pic.png
|
||||
// This method is used in image check on post preview and load, as proxied images have lazy loading
|
||||
// and wouldn't be present on disk but still valid as they will be loaded the first time someone requests them.
|
||||
func (s *Service) ExtractNonProxiedPictures(commentHTML string) (ids []string) {
|
||||
return s.extractImageIDs(commentHTML, false)
|
||||
}
|
||||
|
||||
// Cleanup runs periodic cleanup with 1.5*ServiceParams.EditDuration. Blocking loop, should be called inside of goroutine by consumer
|
||||
@@ -262,6 +237,43 @@ func (s *Service) ImgContentType(img []byte) string {
|
||||
return contentType
|
||||
}
|
||||
|
||||
// returns list of image IDs from the comment html, including proxied images if includeProxied is true
|
||||
func (s *Service) extractImageIDs(commentHTML string, includeProxied bool) (ids []string) {
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(commentHTML))
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] can't parse commentHTML to parse images: %q, error: %v", commentHTML, err)
|
||||
return nil
|
||||
}
|
||||
doc.Find("img").Each(func(i int, sl *goquery.Selection) {
|
||||
if im, ok := sl.Attr("src"); ok {
|
||||
if strings.Contains(im, s.ImageAPI) {
|
||||
elems := strings.Split(im, "/")
|
||||
if len(elems) >= 2 {
|
||||
id := elems[len(elems)-2] + "/" + elems[len(elems)-1]
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
if includeProxied && strings.Contains(im, s.ProxyAPI) {
|
||||
proxiedURL, err := url.Parse(im)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
imgURL, err := base64.URLEncoding.DecodeString(proxiedURL.Query().Get("src"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
imgID, err := CachedImgID(string(imgURL))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ids = append(ids, imgID)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return ids
|
||||
}
|
||||
|
||||
// prepareImage calls readAndValidateImage and resize on provided image.
|
||||
func (s *Service) prepareImage(r io.Reader) ([]byte, error) {
|
||||
data, err := readAndValidateImage(r, s.MaxSize)
|
||||
|
||||
@@ -105,6 +105,7 @@ func TestService_ExtractPictures(t *testing.T) {
|
||||
ids = svc.ExtractPictures(html)
|
||||
require.Equal(t, 1, len(ids), "one image in")
|
||||
assert.Equal(t, "cached_images/12318fbd4c55e9d177b8b5ae197bc89c5afd8e07-a41fcb00643f28d700504256ec81cbf2e1aac53e", ids[0])
|
||||
require.Empty(t, svc.ExtractNonProxiedPictures(html), "no non-proxied images expected to be found")
|
||||
|
||||
// bad url
|
||||
html = `<img src=" https://remark42.radio-t.com/api/v1/img">`
|
||||
@@ -150,7 +151,7 @@ func TestService_Submit(t *testing.T) {
|
||||
svc := NewService(&store, ServiceParams{ImageAPI: "/blah/", EditDuration: time.Millisecond * 100})
|
||||
svc.Submit(func() []string { return []string{"id1", "id2", "id3"} })
|
||||
assert.Equal(t, 3, len(store.ResetCleanupTimerCalls()))
|
||||
err := svc.SubmitAndCommit(func() []string { return []string{"id4", "id5"} })
|
||||
err := svc.Commit(func() []string { return []string{"id4", "id5"} })
|
||||
assert.NoError(t, err)
|
||||
svc.Submit(func() []string { return []string{"id6", "id7"} })
|
||||
assert.Equal(t, 5, len(store.ResetCleanupTimerCalls()))
|
||||
@@ -286,3 +287,11 @@ func TestCachedImgID(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "cached_images/"+Sha1Str("example.org")+"-"+Sha1Str(imgURL), img)
|
||||
}
|
||||
|
||||
func TestService_DoubleClose(*testing.T) {
|
||||
store := StoreMock{}
|
||||
svc := NewService(&store, ServiceParams{EditDuration: 20 * time.Millisecond})
|
||||
svc.Close(context.TODO())
|
||||
// second call should not result in panic
|
||||
svc.Close(context.TODO())
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
log "github.com/go-pkgz/lgr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
bf "github.com/russross/blackfriday/v2"
|
||||
|
||||
"github.com/umputun/remark42/backend/app/store"
|
||||
"github.com/umputun/remark42/backend/app/store/admin"
|
||||
@@ -278,7 +279,7 @@ func (s *DataStore) submitImages(comment store.Comment) {
|
||||
|
||||
var err error
|
||||
if comment.Imported {
|
||||
err = s.ImageService.SubmitAndCommit(idsFn)
|
||||
err = s.ImageService.Commit(idsFn)
|
||||
} else {
|
||||
s.ImageService.Submit(idsFn)
|
||||
}
|
||||
@@ -627,7 +628,9 @@ func (s *DataStore) Counts(siteID string, postIDs []string) ([]store.PostInfo, e
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ValidateComment checks if comment size below max and user fields set
|
||||
// ValidateComment checks if comment size below max and user fields set.
|
||||
// It also validates the absence of relative links as they are almost never the intention of the commenter,
|
||||
// usually added by mistakes and only create confusion.
|
||||
func (s *DataStore) ValidateComment(c *store.Comment) error {
|
||||
maxSize := s.MaxCommentSize
|
||||
if s.MaxCommentSize <= 0 {
|
||||
@@ -642,7 +645,21 @@ func (s *DataStore) ValidateComment(c *store.Comment) error {
|
||||
if c.User.ID == "" || c.User.Name == "" {
|
||||
return fmt.Errorf("empty user info")
|
||||
}
|
||||
return nil
|
||||
|
||||
mdExt, rend := store.GetMdExtensionsAndRenderer()
|
||||
parser := bf.New(bf.WithRenderer(rend), bf.WithExtensions(bf.CommonExtensions), bf.WithExtensions(mdExt))
|
||||
var wrongLinkError error
|
||||
parser.Parse([]byte(c.Orig)).Walk(func(node *bf.Node, entering bool) bf.WalkStatus {
|
||||
if len(node.LinkData.Destination) != 0 &&
|
||||
!(strings.HasPrefix(string(node.LinkData.Destination), "http://") ||
|
||||
strings.HasPrefix(string(node.LinkData.Destination), "https://") ||
|
||||
strings.HasPrefix(string(node.LinkData.Destination), "mailto:")) {
|
||||
wrongLinkError = fmt.Errorf("links should start with mailto:, http:// or https://")
|
||||
return bf.Terminate
|
||||
}
|
||||
return bf.GoToNext
|
||||
})
|
||||
return wrongLinkError
|
||||
}
|
||||
|
||||
// IsAdmin checks if usesID in the list of admins
|
||||
|
||||
@@ -413,7 +413,6 @@ func TestService_VoteAggressive(t *testing.T) {
|
||||
assert.Equal(t, 0, len(res[0].VotedIPs), "vote ips hidden")
|
||||
|
||||
// random +1/-1 result should be [0..2]
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -780,22 +779,25 @@ func TestService_ValidateComment(t *testing.T) {
|
||||
|
||||
tbl := []struct {
|
||||
inp store.Comment
|
||||
err error
|
||||
err string
|
||||
}{
|
||||
{inp: store.Comment{}, err: fmt.Errorf("empty comment text")},
|
||||
{inp: store.Comment{Orig: "something blah", User: store.User{ID: "myid", Name: "name"}}, err: nil},
|
||||
{inp: store.Comment{Orig: "something blah", User: store.User{ID: "myid"}}, err: fmt.Errorf("empty user info")},
|
||||
{inp: store.Comment{Orig: longText, User: store.User{ID: "myid", Name: "name"}}, err: fmt.Errorf("comment text exceeded max allowed size 2000 (4000)")},
|
||||
{inp: store.Comment{}, err: "empty comment text"},
|
||||
{inp: store.Comment{Orig: "something blah", User: store.User{ID: "myid", Name: "name"}}, err: ""},
|
||||
{inp: store.Comment{Orig: "something blah", User: store.User{ID: "myid"}}, err: "empty user info"},
|
||||
{inp: store.Comment{Orig: longText, User: store.User{ID: "myid", Name: "name"}}, err: "comment text exceeded max allowed size 2000 (4000)"},
|
||||
{inp: store.Comment{Orig: "here is a link with relative URL: [google.com](url)", User: store.User{ID: "myid", Name: "name"}}, err: "links should start with mailto:, http:// or https://"},
|
||||
{inp: store.Comment{Orig: "here is a link with relative URL: [google.com](url)", User: store.User{ID: "myid", Name: "name"}}, err: "links should start with mailto:, http:// or https://"},
|
||||
{inp: store.Comment{Orig: "multiple links, one is bad: [test](http://test) [test2](bad_url) [test3](https://test3)", User: store.User{ID: "myid", Name: "name"}}, err: "links should start with mailto:, http:// or https://"},
|
||||
}
|
||||
|
||||
for n, tt := range tbl {
|
||||
err := b.ValidateComment(&tt.inp)
|
||||
if tt.err == nil {
|
||||
if tt.err == "" {
|
||||
assert.NoError(t, err, "check #%d", n)
|
||||
continue
|
||||
}
|
||||
require.Error(t, err)
|
||||
assert.EqualError(t, tt.err, err.Error(), "check #%d", n)
|
||||
assert.EqualError(t, err, tt.err, "check #%d", n)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1638,6 +1640,30 @@ func Benchmark_ServiceCreate(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_DoubleClose_Bolt(t *testing.T) {
|
||||
dbFile := fmt.Sprintf("%s/test-remark42-%d.db", os.TempDir(), rand.Intn(9999999999))
|
||||
defer func() { _ = os.Remove(dbFile) }()
|
||||
|
||||
boltStore, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: dbFile, SiteID: "radio-t"})
|
||||
svc := DataStore{Engine: boltStore, EditDuration: 50 * time.Millisecond, AdminStore: admin.NewStaticKeyStore("secret 123")}
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, boltStore.Close())
|
||||
assert.NoError(t, boltStore.Close(), "second call should not result in panic or errors")
|
||||
assert.NoError(t, svc.Close())
|
||||
assert.NoError(t, svc.Close(), "second call should not result in panic or errors")
|
||||
}
|
||||
|
||||
func TestService_DoubleClose_Static(t *testing.T) {
|
||||
ks := admin.NewStaticKeyStore("secret 123")
|
||||
eng, teardown := prepStoreEngine(t)
|
||||
defer teardown()
|
||||
b := DataStore{Engine: eng, AdminStore: ks,
|
||||
TitleExtractor: NewTitleExtractor(http.Client{Timeout: 5 * time.Second})}
|
||||
b.Close()
|
||||
// second call should not result in panic or errors
|
||||
b.Close()
|
||||
}
|
||||
|
||||
// makes new boltdb, put two records
|
||||
func prepStoreEngine(t *testing.T) (e engine.Interface, teardown func()) {
|
||||
testDBLoc, err := os.MkdirTemp("", "test_image_r42")
|
||||
|
||||
@@ -123,3 +123,10 @@ func TestTitle_GetFailed(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, int32(1), atomic.LoadInt32(&hits), "hit once, errors cached")
|
||||
}
|
||||
|
||||
func TestTitle_DoubleClosed(*testing.T) {
|
||||
ex := NewTitleExtractor(http.Client{Timeout: 5 * time.Second})
|
||||
ex.Close()
|
||||
// second call should not result in panic
|
||||
ex.Close()
|
||||
}
|
||||
|
||||
+40
-40
@@ -1,78 +1,78 @@
|
||||
module github.com/umputun/remark42/backend
|
||||
|
||||
go 1.17
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Depado/bfchroma/v2 v2.0.0
|
||||
github.com/PuerkitoBio/goquery v1.8.0
|
||||
github.com/alecthomas/chroma/v2 v2.3.0
|
||||
github.com/PuerkitoBio/goquery v1.8.1
|
||||
github.com/alecthomas/chroma/v2 v2.8.0
|
||||
github.com/didip/tollbooth/v7 v7.0.1
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
github.com/go-chi/chi/v5 v5.0.10
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-chi/render v1.0.2
|
||||
github.com/go-pkgz/auth v1.20.0
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/go-pkgz/auth v1.21.1-0.20230820223834-cea049c06aa5
|
||||
github.com/go-pkgz/jrpc v0.3.0
|
||||
github.com/go-pkgz/lcw v1.0.1
|
||||
github.com/go-pkgz/lgr v0.10.4
|
||||
github.com/go-pkgz/lcw v1.0.2
|
||||
github.com/go-pkgz/lgr v0.11.0
|
||||
github.com/go-pkgz/notify v0.2.0
|
||||
github.com/go-pkgz/repeater v1.1.3
|
||||
github.com/go-pkgz/rest v1.16.0
|
||||
github.com/go-pkgz/syncs v1.2.0
|
||||
github.com/go-pkgz/rest v1.17.0
|
||||
github.com/go-pkgz/syncs v1.3.2
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/feeds v1.1.1
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/jessevdk/go-flags v1.5.0
|
||||
github.com/kyokomi/emoji/v2 v2.2.10
|
||||
github.com/microcosm-cc/bluemonday v1.0.20
|
||||
github.com/rs/xid v1.4.0
|
||||
github.com/kyokomi/emoji/v2 v2.2.12
|
||||
github.com/microcosm-cc/bluemonday v1.0.25
|
||||
github.com/rs/xid v1.5.0
|
||||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.8.0
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
go.uber.org/goleak v1.2.0
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
go.uber.org/goleak v1.2.1
|
||||
golang.org/x/crypto v0.12.0
|
||||
golang.org/x/image v0.11.0
|
||||
golang.org/x/net v0.14.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.6.1 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dghubble/oauth1 v0.7.1 // indirect
|
||||
github.com/dghubble/oauth1 v0.7.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.1 // indirect
|
||||
github.com/go-pkgz/email v0.4.0 // indirect
|
||||
github.com/go-pkgz/expirable-cache v0.1.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.2 // indirect
|
||||
github.com/go-pkgz/email v0.4.1 // indirect
|
||||
github.com/go-pkgz/expirable-cache v1.0.0 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/klauspost/compress v1.15.2 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/slack-go/slack v0.11.3 // indirect
|
||||
github.com/slack-go/slack v0.12.2 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.mongodb.org/mongo-driver v1.10.2 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
go.mongodb.org/mongo-driver v1.12.1 // indirect
|
||||
golang.org/x/oauth2 v0.11.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
+103
-584
@@ -1,106 +1,40 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
|
||||
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
|
||||
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
|
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
|
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
|
||||
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
|
||||
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
|
||||
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
|
||||
cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
|
||||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
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/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
github.com/Depado/bfchroma/v2 v2.0.0 h1:IRpN9BPkNwEpR6w1ectIcNWOuhDSLx+8f1pn83fzxx8=
|
||||
github.com/Depado/bfchroma/v2 v2.0.0/go.mod h1:wFwW/Pw8Tnd0irzgO9Zxtxgzp3aPS8qBWlyadxujxmw=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0 h1:83xfxrnjv8eK+Cf8qZDzNo3PPF9IbTWHs7z28GY6D0U=
|
||||
github.com/alecthomas/chroma/v2 v2.3.0/go.mod h1:mZxeWZlxP2Dy+/8cBob2PYd8O2DwNAzave5AY7A2eQw=
|
||||
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
|
||||
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
|
||||
github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264=
|
||||
github.com/alecthomas/chroma/v2 v2.8.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw=
|
||||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.22.0 h1:lIHHiSkEyS1MkKHCHzN+0mWrA4YdbGdimE5iZ2sHSzo=
|
||||
github.com/alicebob/miniredis/v2 v2.22.0/go.mod h1:XNqvJdQJv5mSuVMc0ynneafpnL/zv52acZ6kqeS0t88=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
|
||||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dghubble/oauth1 v0.7.1 h1:JjbOVSVVkms9A4h/sTQy5Jb2nFuAAVb2qVYgenJPyrE=
|
||||
github.com/dghubble/oauth1 v0.7.1/go.mod h1:0eEzON0UY/OLACQrmnjgJjmvCGXzjBCsZqL1kWDXtF0=
|
||||
github.com/dghubble/oauth1 v0.7.2 h1:pwcinOZy8z6XkNxvPmUDY52M7RDPxt0Xw1zgZ6Cl5JA=
|
||||
github.com/dghubble/oauth1 v0.7.2/go.mod h1:9erQdIhqhOHG/7K9s/tgh9Ks/AfoyrO5mW/43Lu2+kE=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/didip/tollbooth/v7 v7.0.0/go.mod h1:VZhDSGl5bDSPj4wPsih3PFa4Uh9Ghv8hgacaTm5PRT4=
|
||||
@@ -108,17 +42,8 @@ github.com/didip/tollbooth/v7 v7.0.1 h1:TkT4sBKoQoHQFPf7blQ54iHrZiTDnr8TceU+MulV
|
||||
github.com/didip/tollbooth/v7 v7.0.1/go.mod h1:VZhDSGl5bDSPj4wPsih3PFa4Uh9Ghv8hgacaTm5PRT4=
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f h1:jtKwihcLmUC9BAhoJ9adCUqdSSZcOdH2KL7mPTUm2aw=
|
||||
github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f/go.mod h1:q9C80dnsuVRP2dAskjnXRNWdUJqtGgwG9wNrzt0019s=
|
||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
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/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
@@ -127,41 +52,38 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
|
||||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
|
||||
github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg=
|
||||
github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.1 h1:3vxp+cjLqDe1TbogbwtMyeHRHr1tD+ksrK7xNppYRDs=
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.1/go.mod h1:wk/2uLImWIa9VVQDgxz99H2GDbhmfi/9/Xr+GvkSUSQ=
|
||||
github.com/go-pkgz/auth v1.20.0 h1:9SHkolgv9+zOI9U+8IFXra0pl/H90oE4+ciJWtXoDl4=
|
||||
github.com/go-pkgz/auth v1.20.0/go.mod h1:jz0djN+4XoCyieuOzc+rB9l0RdqeuiXoQfE02yonLAI=
|
||||
github.com/go-pkgz/email v0.3.1-0.20221002173339-19d25a20d99c/go.mod h1:TpnmSLkQW3FyICit2hn7WIhCUDrhCX6btzz5wS3wHRI=
|
||||
github.com/go-pkgz/email v0.4.0 h1:NiYCwKPR6sW8nJsOR3GyB9Yw1AQZdnY78Xnhd9SLHEs=
|
||||
github.com/go-pkgz/email v0.4.0/go.mod h1:TpnmSLkQW3FyICit2hn7WIhCUDrhCX6btzz5wS3wHRI=
|
||||
github.com/go-pkgz/expirable-cache v0.1.0 h1:3bw0m8vlTK8qlwz5KXuygNBTkiKRTPrAGXU0Ej2AC1g=
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.2 h1:CuZhD3lhGuI6aNLyUbRHXsgG2RwGRBOuCBfd4WQKqBQ=
|
||||
github.com/go-oauth2/oauth2/v4 v4.5.2/go.mod h1:wk/2uLImWIa9VVQDgxz99H2GDbhmfi/9/Xr+GvkSUSQ=
|
||||
github.com/go-pkgz/auth v1.21.1-0.20230820223834-cea049c06aa5 h1:iSiyXXA0sbLJGb1ZgR8PRTizs1wK2QZ/TXG1frUEprw=
|
||||
github.com/go-pkgz/auth v1.21.1-0.20230820223834-cea049c06aa5/go.mod h1:knVxcFhXlZ9AUvB1nlOR0kWghVBcgfFH1ucPW9CjCmE=
|
||||
github.com/go-pkgz/email v0.4.1 h1:2vtP2gibsSzqhz6eD5DklSp11m657XEVf17fuXaxMvk=
|
||||
github.com/go-pkgz/email v0.4.1/go.mod h1:BdxglsQnymzhfdbnncEE72a6DrucZHy6I+42LK2jLEc=
|
||||
github.com/go-pkgz/expirable-cache v0.1.0/go.mod h1:GTrEl0X+q0mPNqN6dtcQXksACnzCBQ5k/k1SwXJsZKs=
|
||||
github.com/go-pkgz/expirable-cache v1.0.0 h1:ns5+1hjY8hntGv8bPaQd9Gr7Jyo+Uw5SLyII40aQdtA=
|
||||
github.com/go-pkgz/expirable-cache v1.0.0/go.mod h1:GTrEl0X+q0mPNqN6dtcQXksACnzCBQ5k/k1SwXJsZKs=
|
||||
github.com/go-pkgz/jrpc v0.3.0 h1:Fls38KqPsHzvp0FWfivr6cGnncC+iFBodHBqvUPY+0U=
|
||||
github.com/go-pkgz/jrpc v0.3.0/go.mod h1:MFtKs75JESiSqVicsQkgN2iDFFuCd3gVT1/vKiwRi00=
|
||||
github.com/go-pkgz/lcw v1.0.1 h1:svYC6LIyzRaHF3TwJ8GCS+2RkJreBfaFjoeS+UYwJBc=
|
||||
github.com/go-pkgz/lcw v1.0.1/go.mod h1:CPJJzunpmGToOtD0Ga82TV152eL69sYEIIPcy9fbxlU=
|
||||
github.com/go-pkgz/lgr v0.10.4 h1:l7qyFjqEZgwRgaQQSEp6tve4A3OU80VrfzpvtEX8ngw=
|
||||
github.com/go-pkgz/lgr v0.10.4/go.mod h1:CD0s1z6EFpIUplV067gitF77tn25JItzwHNKAPqeCF0=
|
||||
github.com/go-pkgz/lcw v1.0.2 h1:68T8xRkVWSo1KIbMfFXBY1xbFF3XWl7YD+ub3jkUlNE=
|
||||
github.com/go-pkgz/lcw v1.0.2/go.mod h1:CPJJzunpmGToOtD0Ga82TV152eL69sYEIIPcy9fbxlU=
|
||||
github.com/go-pkgz/lgr v0.11.0 h1:9XH5o+vj09L0sRWEswIGK1lJ6g07xVB4/Z28RV9Z+qM=
|
||||
github.com/go-pkgz/lgr v0.11.0/go.mod h1:4rdRmMSs4yGFjnUg0rSDbKx21LmFNZoH4y8OLl3qDnU=
|
||||
github.com/go-pkgz/notify v0.2.0 h1:mxHjcLc3goT+k1qnBPJ06PpNuVUDcu21Xy+6hEo4IaU=
|
||||
github.com/go-pkgz/notify v0.2.0/go.mod h1:uB4bcohkZB+P8zT279KQv5aXqQEkeMXI3Ey0Y3r0SQk=
|
||||
github.com/go-pkgz/repeater v1.1.3 h1:q6+JQF14ESSy28Dd7F+wRelY4F+41HJ0LEy/szNnMiE=
|
||||
github.com/go-pkgz/repeater v1.1.3/go.mod h1:hVTavuO5x3Gxnu8zW7d6sQBfAneKV8X2FjU48kGfpKw=
|
||||
github.com/go-pkgz/rest v1.15.6/go.mod h1:KUWAqbDteYGS/CiXftomQsKjtEOifXsJ36Ka0skYbmk=
|
||||
github.com/go-pkgz/rest v1.16.0 h1:3An51XJXUq1XtICHvfAEp048ZCbUHBEga3g0WEu3zK0=
|
||||
github.com/go-pkgz/rest v1.16.0/go.mod h1:HHlLOt02NJc2sgffXBF6hYVMcRo4Gz3vjg43zTzN7VM=
|
||||
github.com/go-pkgz/syncs v1.2.0 h1:aiizQFILlMZ4KtRNaYLcDffRbUQZH9fclsgr5KybWyY=
|
||||
github.com/go-pkgz/syncs v1.2.0/go.mod h1:fjThZdM2FkC/oSeiqBTOZOtHpbrCh4HuHbipB5qZJJM=
|
||||
github.com/go-pkgz/rest v1.17.0 h1:LoBI/lDBMuqwWhOOkc6thM9NnwJO+K9nWvCOjZ7BAgE=
|
||||
github.com/go-pkgz/rest v1.17.0/go.mod h1:HHlLOt02NJc2sgffXBF6hYVMcRo4Gz3vjg43zTzN7VM=
|
||||
github.com/go-pkgz/syncs v1.3.2 h1:gmioASlJNy3gNosPlgvWOM2QP0Hdjzn2u+/sUShgd8E=
|
||||
github.com/go-pkgz/syncs v1.3.2/go.mod h1:qjgzpp7OpuhDf7BWsW/FHCu9DLjE32NPy6/vXAXT/Cw=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
|
||||
@@ -171,89 +93,34 @@ github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
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.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
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.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/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/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.4/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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
|
||||
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
|
||||
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
@@ -262,45 +129,40 @@ github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBba
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
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/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw=
|
||||
github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kyokomi/emoji/v2 v2.2.10 h1:1z5eMVcxFifsmEoNpdeq4UahbcicgQ4FEHuzrCVwmiI=
|
||||
github.com/kyokomi/emoji/v2 v2.2.10/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.12 h1:sSVA5nH9ebR3Zji1o31wu3yOwD1zKXQA2z0zUyeit60=
|
||||
github.com/kyokomi/emoji/v2 v2.2.12/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y=
|
||||
github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 h1:Ys0rDzh8s4UMlGaDa1UTA0sfKgvF0hQZzTYX8ktjiDc=
|
||||
@@ -320,15 +182,11 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
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/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
@@ -336,11 +194,10 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/slack-go/slack v0.11.3 h1:GN7revxEMax4amCc3El9a+9SGnjmBvSUobs0QnO6ZO8=
|
||||
github.com/slack-go/slack v0.11.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ=
|
||||
github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@@ -350,8 +207,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/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.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E=
|
||||
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8=
|
||||
github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo=
|
||||
@@ -378,10 +236,10 @@ github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oa
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
@@ -398,462 +256,133 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw=
|
||||
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.mongodb.org/mongo-driver v1.10.2 h1:4Wk3cnqOrQCn0P92L3/mmurMxzdvWWs5J9jinAVKD+k=
|
||||
go.mongodb.org/mongo-driver v1.10.2/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=
|
||||
go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/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-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
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-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-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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-20191011141410-1b5146add898/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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
|
||||
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
|
||||
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
|
||||
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
|
||||
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
|
||||
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
|
||||
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
|
||||
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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
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.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
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.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
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-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
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 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
@@ -862,13 +391,3 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
||||
+17
-2
@@ -119,12 +119,27 @@ GET {{host}}/api/v1/rss/reply?site={{site}}&user={{user}}
|
||||
GET {{host}}/api/v1/avatar/blah
|
||||
|
||||
### send confirmation token for current user to specified email. auth token for dev user for secret=12345.
|
||||
POST {{host}}/api/v1/email/subscribe?site={{site}}&address={{email}}
|
||||
### in case the user logged in with the same email, it will be confirmed right away with "updated" set to "true" in the response,
|
||||
### and no email will be sent.
|
||||
POST {{host}}/api/v1/email/subscribe
|
||||
X-JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcmsiLCJleHAiOjE5NzYwNTY3NTYsImp0aSI6IjJlOGJmMTE5OTI0MjQxMDRjYjFhZGRlODllMWYwNGFiMTg4YWZjMzQiLCJpYXQiOjE1NzYwNTY0NTYsImlzcyI6InJlbWFyazQyIiwidXNlciI6eyJuYW1lIjoiZGV2X3VzZXIiLCJpZCI6ImRldl91c2VyIiwicGljdHVyZSI6Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9hcGkvdjEvYXZhdGFyL2NjZmEyYWJkMDE2Njc2MDViNGUxZmM0ZmNiOTFiMWUxYWYzMjMyNDAuaW1hZ2UiLCJhdHRycyI6eyJhZG1pbiI6dHJ1ZSwiYmxvY2tlZCI6ZmFsc2V9fX0.6Qt5s2enBMRC-Jmsua01yViVYI95Dx6BPBMaNjj36d4
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"site": "{{site}}",
|
||||
"address": "{{email}}"
|
||||
}
|
||||
|
||||
|
||||
### add email for notifications for current user via token from email. auth token for dev user for secret=12345.
|
||||
POST {{host}}/api/v1/email/confirm?site={{site}}&tkn={{token}}
|
||||
POST {{host}}/api/v1/email/confirm
|
||||
X-JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyZW1hcmsiLCJleHAiOjE5NzYwNTY3NTYsImp0aSI6IjJlOGJmMTE5OTI0MjQxMDRjYjFhZGRlODllMWYwNGFiMTg4YWZjMzQiLCJpYXQiOjE1NzYwNTY0NTYsImlzcyI6InJlbWFyazQyIiwidXNlciI6eyJuYW1lIjoiZGV2X3VzZXIiLCJpZCI6ImRldl91c2VyIiwicGljdHVyZSI6Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9hcGkvdjEvYXZhdGFyL2NjZmEyYWJkMDE2Njc2MDViNGUxZmM0ZmNiOTFiMWUxYWYzMjMyNDAuaW1hZ2UiLCJhdHRycyI6eyJhZG1pbiI6dHJ1ZSwiYmxvY2tlZCI6ZmFsc2V9fX0.6Qt5s2enBMRC-Jmsua01yViVYI95Dx6BPBMaNjj36d4
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"site": "{{site}}",
|
||||
"token": "{{token}}"
|
||||
}
|
||||
|
||||
### get current user email. auth token for dev user for secret=12345.
|
||||
GET {{host}}/api/v1/email?site={{site}}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package internal
|
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "1.23.0"
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Changes
|
||||
|
||||
## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.2...compute/metadata/v0.2.3) (2022-12-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compute/metadata:** Switch DNS lookup to an absolute lookup ([119b410](https://github.com/googleapis/google-cloud-go/commit/119b41060c7895e45e48aee5621ad35607c4d021)), refs [#7165](https://github.com/googleapis/google-cloud-go/issues/7165)
|
||||
|
||||
## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.1...compute/metadata/v0.2.2) (2022-12-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compute/metadata:** Set IdleConnTimeout for http.Client ([#7084](https://github.com/googleapis/google-cloud-go/issues/7084)) ([766516a](https://github.com/googleapis/google-cloud-go/commit/766516aaf3816bfb3159efeea65aa3d1d205a3e2)), refs [#5430](https://github.com/googleapis/google-cloud-go/issues/5430)
|
||||
|
||||
## [0.1.0] (2022-10-26)
|
||||
|
||||
Initial release of metadata being it's own module.
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
# Compute API
|
||||
|
||||
[](https://pkg.go.dev/cloud.google.com/go/compute/metadata)
|
||||
|
||||
This is a utility library for communicating with Google Cloud metadata service
|
||||
on Google Cloud.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get cloud.google.com/go/compute/metadata
|
||||
```
|
||||
|
||||
## Go Version Support
|
||||
|
||||
See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported)
|
||||
section in the root directory's README.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md)
|
||||
document for details.
|
||||
|
||||
Please note that this project is released with a Contributor Code of Conduct.
|
||||
By participating in this project you agree to abide by its terms. See
|
||||
[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct)
|
||||
for more information.
|
||||
+4
-2
@@ -16,7 +16,7 @@
|
||||
// metadata and API service accounts.
|
||||
//
|
||||
// This package is a wrapper around the GCE metadata service,
|
||||
// as documented at https://developers.google.com/compute/docs/metadata.
|
||||
// as documented at https://cloud.google.com/compute/docs/metadata/overview.
|
||||
package metadata // import "cloud.google.com/go/compute/metadata"
|
||||
|
||||
import (
|
||||
@@ -70,7 +70,9 @@ func newDefaultHTTPClient() *http.Client {
|
||||
Timeout: 2 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +147,7 @@ func testOnGCE() bool {
|
||||
|
||||
go func() {
|
||||
resolver := &net.Resolver{}
|
||||
addrs, err := resolver.LookupHost(ctx, "metadata.google.internal")
|
||||
addrs, err := resolver.LookupHost(ctx, "metadata.google.internal.")
|
||||
if err != nil || len(addrs) == 0 {
|
||||
resc <- false
|
||||
return
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file, and the {{.RootMod}} import, won't actually become part of
|
||||
// the resultant binary.
|
||||
//go:build modhack
|
||||
// +build modhack
|
||||
|
||||
package metadata
|
||||
|
||||
// Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
||||
import _ "cloud.google.com/go/compute/internal"
|
||||
+3
@@ -40,6 +40,7 @@ Please note that because of the net/html dependency, goquery requires Go1.1+ and
|
||||
|
||||
**Note that goquery's API is now stable, and will not break.**
|
||||
|
||||
* **2023-02-18 (v1.8.1)** : Update `go.mod` dependencies, update CI workflow.
|
||||
* **2021-10-25 (v1.8.0)** : Add `Render` function to render a `Selection` to an `io.Writer` (thanks [@anthonygedeon](https://github.com/anthonygedeon)).
|
||||
* **2021-07-11 (v1.7.1)** : Update go.mod dependencies and add dependabot config (thanks [@jauderho](https://github.com/jauderho)).
|
||||
* **2021-06-14 (v1.7.0)** : Add `Single` and `SingleMatcher` functions to optimize first-match selection (thanks [@gdollardollar](https://github.com/gdollardollar)).
|
||||
@@ -154,6 +155,8 @@ func main() {
|
||||
- [Geziyor](https://github.com/geziyor/geziyor), a fast web crawling & scraping framework for Go. Supports JS rendering.
|
||||
- [Pagser](https://github.com/foolin/pagser), a simple, easy, extensible, configurable HTML parser to struct based on goquery and struct tags.
|
||||
- [stitcherd](https://github.com/vhodges/stitcherd), A server for doing server side includes using css selectors and DOM updates.
|
||||
- [goskyr](https://github.com/jakopako/goskyr), an easily configurable command-line scraper written in Go.
|
||||
- [goGetJS](https://github.com/davemolk/goGetJS), a tool for extracting, searching, and saving JavaScript files (with optional headless browser).
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
+3
-3
@@ -58,8 +58,8 @@ func nodeName(node *html.Node) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Render renders the html of the first element from selector and writes it to
|
||||
// the writer. It behaves the same as OuterHtml but writes to w instead of
|
||||
// Render renders the HTML of the first item in the selection and writes it to
|
||||
// the writer. It behaves the same as OuterHtml but writes to w instead of
|
||||
// returning the string.
|
||||
func Render(w io.Writer, s *Selection) error {
|
||||
if s.Length() == 0 {
|
||||
@@ -73,7 +73,7 @@ func Render(w io.Writer, s *Selection) error {
|
||||
// the selection - that is, the HTML including the first element's
|
||||
// tag and attributes.
|
||||
//
|
||||
// Unlike InnerHtml, this is a function and not a method on the Selection,
|
||||
// Unlike Html, this is a function and not a method on the Selection,
|
||||
// because this is not a jQuery method (in javascript-land, this is
|
||||
// a property provided by the DOM).
|
||||
func OuterHtml(s *Selection) (string, error) {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.xml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = false
|
||||
@@ -17,3 +17,4 @@
|
||||
_models/
|
||||
|
||||
_examples/
|
||||
*.min.*
|
||||
|
||||
+12
@@ -37,6 +37,18 @@ linters:
|
||||
- wrapcheck
|
||||
- stylecheck
|
||||
- thelper
|
||||
- nonamedreturns
|
||||
- revive
|
||||
- dupword
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- forcetypeassert
|
||||
- ireturn
|
||||
- maintidx
|
||||
- govet
|
||||
- nosnakecase
|
||||
- testableexamples
|
||||
- musttag
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
|
||||
+5
-1
@@ -1,6 +1,8 @@
|
||||
.PHONY: chromad upload all
|
||||
|
||||
VERSION ?= $(shell git describe --tags --dirty --always)
|
||||
export GOOS ?= linux
|
||||
export GOARCH ?= amd64
|
||||
|
||||
all: README.md tokentype_string.go
|
||||
|
||||
@@ -12,7 +14,9 @@ tokentype_string.go: types.go
|
||||
|
||||
chromad:
|
||||
rm -f chromad
|
||||
(export CGOENABLED=0 GOOS=linux GOARCH=amd64; cd ./cmd/chromad && go build -ldflags="-X 'main.version=$(VERSION)'" -o ../../chromad .)
|
||||
esbuild --bundle cmd/chromad/static/index.js --minify --outfile=cmd/chromad/static/index.min.js
|
||||
esbuild --bundle cmd/chromad/static/index.css --minify --outfile=cmd/chromad/static/index.min.css
|
||||
(export CGOENABLED=0 ; cd ./cmd/chromad && go build -ldflags="-X 'main.version=$(VERSION)'" -o ../../chromad .)
|
||||
|
||||
upload: chromad
|
||||
scp chromad root@swapoff.org: && \
|
||||
|
||||
+40
-20
@@ -27,7 +27,8 @@ translators for Pygments lexers and styles.
|
||||
2. [Formatters](#formatters)
|
||||
3. [Styles](#styles)
|
||||
6. [Command-line interface](#command-line-interface)
|
||||
7. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments)
|
||||
7. [Testing lexers](#testing-lexers)
|
||||
8. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
@@ -36,27 +37,27 @@ translators for Pygments lexers and styles.
|
||||
|
||||
Prefix | Language
|
||||
:----: | --------
|
||||
A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, Arduino, Awk
|
||||
B | Ballerina, Base Makefile, Bash, Batchfile, BibTeX, Bicep, BlitzBasic, BNF, Brainfuck
|
||||
A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, Awk
|
||||
B | Ballerina, Bash, Batchfile, BibTeX, Bicep, BlitzBasic, BNF, Brainfuck, BQN
|
||||
C | C, C#, C++, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Chapel, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Crystal, CSS, Cython
|
||||
D | D, Dart, Diff, Django/Jinja, Docker, DTD, Dylan
|
||||
E | EBNF, Elixir, Elm, EmacsLisp, Erlang
|
||||
F | Factor, Fish, Forth, Fortran, FSharp
|
||||
G | GAS, GDScript, Genshi, Genshi HTML, Genshi Text, Gherkin, GLSL, Gnuplot, Go, Go HTML Template, Go Text Template, GraphQL, Groff, Groovy
|
||||
H | Handlebars, Haskell, Haxe, HCL, Hexdump, HLB, HTML, HTTP, Hy
|
||||
H | Handlebars, Haskell, Haxe, HCL, Hexdump, HLB, HLSL, HTML, HTTP, Hy
|
||||
I | Idris, Igor, INI, Io
|
||||
J | J, Java, JavaScript, JSON, Julia, Jungle
|
||||
K | Kotlin
|
||||
L | Lighttpd configuration file, LLVM, Lua
|
||||
M | Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, MLIR, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
|
||||
M | Makefile, Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, MLIR, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
|
||||
N | NASM, Newspeak, Nginx configuration file, Nim, Nix
|
||||
O | Objective-C, OCaml, Octave, OnesEnterprise, OpenEdge ABL, OpenSCAD, Org Mode
|
||||
P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, PromQL, Properties, Protocol Buffer, Puppet, Python 2, Python
|
||||
P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, PromQL, Properties, Protocol Buffer, PSL, Puppet, Python 2, Python
|
||||
Q | QBasic
|
||||
R | R, Racket, Ragel, Raku, react, ReasonML, reg, reStructuredText, Rexx, Ruby, Rust
|
||||
S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, Snobol, Solidity, SPARQL, SQL, SquidConf, Standard ML, Stylus, Svelte, Swift, SYSTEMD, systemverilog
|
||||
S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Sed, Smali, Smalltalk, Smarty, Snobol, Solidity, SPARQL, SQL, SquidConf, Standard ML, stas, Stylus, Svelte, Swift, SYSTEMD, systemverilog
|
||||
T | TableGen, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData
|
||||
V | VB.net, verilog, VHDL, VimL, vue
|
||||
V | VB.net, verilog, VHDL, VHS, VimL, vue
|
||||
W | WDTE
|
||||
X | XML, Xorg
|
||||
Y | YAML, YANG
|
||||
@@ -185,7 +186,7 @@ following constructor options:
|
||||
- `ClassPrefix(prefix)` - prefix each generated CSS class.
|
||||
- `TabWidth(width)` - Set the rendered tab width, in characters.
|
||||
- `WithLineNumbers()` - Render line numbers (style with `LineNumbers`).
|
||||
- `LinkableLineNumbers()` - Make the line numbers linkable and be a link to themselves.
|
||||
- `WithLinkableLineNumbers()` - Make the line numbers linkable and be a link to themselves.
|
||||
- `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`).
|
||||
- `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans.
|
||||
|
||||
@@ -207,14 +208,13 @@ for details on implementing lexers. Most concepts apply directly to Chroma,
|
||||
but see existing lexer implementations for real examples.
|
||||
|
||||
In many cases lexers can be automatically converted directly from Pygments by
|
||||
using the included Python 3 script `pygments2chroma.py`. I use something like
|
||||
using the included Python 3 script `pygments2chroma_xml.py`. I use something like
|
||||
the following:
|
||||
|
||||
```sh
|
||||
python3 _tools/pygments2chroma.py \
|
||||
python3 _tools/pygments2chroma_xml.py \
|
||||
pygments.lexers.jvm.KotlinLexer \
|
||||
> lexers/k/kotlin.go \
|
||||
&& gofmt -s -w lexers/k/kotlin.go
|
||||
> lexers/embedded/kotlin.xml
|
||||
```
|
||||
|
||||
See notes in [pygments-lexers.txt](https://github.com/alecthomas/chroma/blob/master/pygments-lexers.txt)
|
||||
@@ -231,17 +231,22 @@ formatter outputs raw tokens. The latter is useful for debugging lexers.
|
||||
<a id="markdown-styles" name="styles"></a>
|
||||
### Styles
|
||||
|
||||
Chroma styles use the [same syntax](http://pygments.org/docs/styles/) as Pygments.
|
||||
Chroma styles are defined in XML. The style entries use the
|
||||
[same syntax](http://pygments.org/docs/styles/) as Pygments.
|
||||
|
||||
All Pygments styles have been converted to Chroma using the `_tools/style.py` script.
|
||||
All Pygments styles have been converted to Chroma using the `_tools/style.py`
|
||||
script.
|
||||
|
||||
When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles), know that the `chroma.Background` token type provides the default style for tokens. It does so by defining a foreground color and background color.
|
||||
When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles),
|
||||
know that the `Background` token type provides the default style for tokens. It does so
|
||||
by defining a foreground color and background color.
|
||||
|
||||
For example, this gives each token name not defined in the style a default color of `#f8f8f8` and uses `#000000` for the highlighted code block's background:
|
||||
For example, this gives each token name not defined in the style a default color
|
||||
of `#f8f8f8` and uses `#000000` for the highlighted code block's background:
|
||||
|
||||
~~~go
|
||||
chroma.Background: "#f8f8f2 bg:#000000",
|
||||
~~~
|
||||
```xml
|
||||
<entry type="Background" style="#f8f8f2 bg:#000000"/>
|
||||
```
|
||||
|
||||
Also, token types in a style file are hierarchical. For instance, when `CommentSpecial` is not defined, Chroma uses the token style from `Comment`. So when several comment tokens use the same color, you'll only need to define `Comment` and override the one that has a different color.
|
||||
|
||||
@@ -273,6 +278,21 @@ Debian and derivatives](https://manpages.debian.org/lesspipe#USER_DEFINED_FILTER
|
||||
for that setup the `chroma` executable can be just symlinked to `~/.lessfilter`.
|
||||
|
||||
<a id="markdown-whats-missing-compared-to-pygments" name="whats-missing-compared-to-pygments"></a>
|
||||
|
||||
<a id="markdown-testing-lexers" name="testing-lexers"></a>
|
||||
## Testing lexers
|
||||
If you edit some lexers and want to try it, open a shell in `cmd/chromad` and run:
|
||||
```shell
|
||||
go run .
|
||||
```
|
||||
A Link will be printed. Open it in your Browser. Now you can test on the Playground with your local changes.
|
||||
|
||||
If you want to run the tests and the lexers, open a shell in the root directory and run:
|
||||
```shell
|
||||
go test ./lexers
|
||||
```
|
||||
When updating or adding a lexer, please add tests. See [lexers/README.md](lexers/README.md) for more.
|
||||
|
||||
## What's missing compared to Pygments?
|
||||
|
||||
- Quite a few lexers, for various reasons (pull-requests welcome):
|
||||
|
||||
+26
-29
@@ -81,42 +81,39 @@ func ByGroupNames(emitters map[string]Emitter) Emitter {
|
||||
}
|
||||
|
||||
// UsingByGroup emits tokens for the matched groups in the regex using a
|
||||
// "sublexer". Used when lexing code blocks where the name of a sublexer is
|
||||
// sublexer. Used when lexing code blocks where the name of a sublexer is
|
||||
// contained within the block, for example on a Markdown text block or SQL
|
||||
// language block.
|
||||
//
|
||||
// The sublexer will be retrieved using sublexerGetFunc (typically
|
||||
// internal.Get), using the captured value from the matched sublexerNameGroup.
|
||||
//
|
||||
// If sublexerGetFunc returns a non-nil lexer for the captured sublexerNameGroup,
|
||||
// then tokens for the matched codeGroup will be emitted using the retrieved
|
||||
// lexer. Otherwise, if the sublexer is nil, then tokens will be emitted from
|
||||
// the passed emitter.
|
||||
// An attempt to load the sublexer will be made using the captured value from
|
||||
// the text of the matched sublexerNameGroup. If a sublexer matching the
|
||||
// sublexerNameGroup is available, then tokens for the matched codeGroup will
|
||||
// be emitted using the sublexer. Otherwise, if no sublexer is available, then
|
||||
// tokens will be emitted from the passed emitter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var Markdown = internal.Register(MustNewLexer(
|
||||
// &Config{
|
||||
// Name: "markdown",
|
||||
// Aliases: []string{"md", "mkd"},
|
||||
// Filenames: []string{"*.md", "*.mkd", "*.markdown"},
|
||||
// MimeTypes: []string{"text/x-markdown"},
|
||||
// },
|
||||
// Rules{
|
||||
// "root": {
|
||||
// {"^(```)(\\w+)(\\n)([\\w\\W]*?)(^```$)",
|
||||
// UsingByGroup(
|
||||
// internal.Get,
|
||||
// 2, 4,
|
||||
// String, String, String, Text, String,
|
||||
// ),
|
||||
// nil,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// ))
|
||||
// var Markdown = internal.Register(MustNewLexer(
|
||||
// &Config{
|
||||
// Name: "markdown",
|
||||
// Aliases: []string{"md", "mkd"},
|
||||
// Filenames: []string{"*.md", "*.mkd", "*.markdown"},
|
||||
// MimeTypes: []string{"text/x-markdown"},
|
||||
// },
|
||||
// Rules{
|
||||
// "root": {
|
||||
// {"^(```)(\\w+)(\\n)([\\w\\W]*?)(^```$)",
|
||||
// UsingByGroup(
|
||||
// 2, 4,
|
||||
// String, String, String, Text, String,
|
||||
// ),
|
||||
// nil,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// ))
|
||||
//
|
||||
// See the lexers/m/markdown.go for the complete example.
|
||||
// See the lexers/markdown.go for the complete example.
|
||||
//
|
||||
// Note: panic's if the number of emitters does not equal the number of matched
|
||||
// groups in the regex.
|
||||
|
||||
+10
-9
@@ -100,9 +100,9 @@ func LineNumbersInTable(b bool) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// LinkableLineNumbers decorates the line numbers HTML elements with an "id"
|
||||
// WithLinkableLineNumbers decorates the line numbers HTML elements with an "id"
|
||||
// attribute so they can be linked.
|
||||
func LinkableLineNumbers(b bool, prefix string) Option {
|
||||
func WithLinkableLineNumbers(b bool, prefix string) Option {
|
||||
return func(f *Formatter) {
|
||||
f.linkableLineNumbers = b
|
||||
f.lineNumbersIDPrefix = prefix
|
||||
@@ -171,10 +171,10 @@ var (
|
||||
defaultPreWrapper = preWrapper{
|
||||
start: func(code bool, styleAttr string) string {
|
||||
if code {
|
||||
return fmt.Sprintf(`<pre tabindex="0"%s><code>`, styleAttr)
|
||||
return fmt.Sprintf(`<pre%s><code>`, styleAttr)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`<pre tabindex="0"%s>`, styleAttr)
|
||||
return fmt.Sprintf(`<pre%s>`, styleAttr)
|
||||
},
|
||||
end: func(code bool) string {
|
||||
if code {
|
||||
@@ -262,7 +262,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
fmt.Fprintf(w, "<span%s>", f.styleAttr(css, chroma.LineHighlight))
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "<span%s%s>%s\n</span>", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(lineDigits, line))
|
||||
fmt.Fprintf(w, "<span%s%s>%s\n</span>", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line))
|
||||
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "</span>")
|
||||
@@ -302,7 +302,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
|
||||
// Line number
|
||||
if f.lineNumbers && !wrapInTable {
|
||||
fmt.Fprintf(w, "<span%s%s>%s</span>", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(lineDigits, line))
|
||||
fmt.Fprintf(w, "<span%s%s>%s</span>", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line))
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, `<span%s>`, f.styleAttr(css, chroma.CodeLine))
|
||||
@@ -345,12 +345,12 @@ func (f *Formatter) lineIDAttribute(line int) string {
|
||||
return fmt.Sprintf(" id=\"%s\"", f.lineID(line))
|
||||
}
|
||||
|
||||
func (f *Formatter) lineTitleWithLinkIfNeeded(lineDigits, line int) string {
|
||||
func (f *Formatter) lineTitleWithLinkIfNeeded(css map[chroma.TokenType]string, lineDigits, line int) string {
|
||||
title := fmt.Sprintf("%*d", lineDigits, line)
|
||||
if !f.linkableLineNumbers {
|
||||
return title
|
||||
}
|
||||
return fmt.Sprintf("<a style=\"outline: none; text-decoration:none; color:inherit\" href=\"#%s\">%s</a>", f.lineID(line), title)
|
||||
return fmt.Sprintf("<a%s href=\"#%s\">%s</a>", f.styleAttr(css, chroma.LineLink), f.lineID(line), title)
|
||||
}
|
||||
|
||||
func (f *Formatter) lineID(line int) string {
|
||||
@@ -513,13 +513,14 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
|
||||
if f.wrapLongLines {
|
||||
classes[chroma.PreWrapper] += `white-space: pre-wrap; word-break: break-word;`
|
||||
}
|
||||
lineNumbersStyle := `white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;`
|
||||
lineNumbersStyle := `white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;`
|
||||
// All rules begin with default rules followed by user provided rules
|
||||
classes[chroma.Line] = `display: flex;` + classes[chroma.Line]
|
||||
classes[chroma.LineNumbers] = lineNumbersStyle + classes[chroma.LineNumbers]
|
||||
classes[chroma.LineNumbersTable] = lineNumbersStyle + classes[chroma.LineNumbersTable]
|
||||
classes[chroma.LineTable] = "border-spacing: 0; padding: 0; margin: 0; border: 0;" + classes[chroma.LineTable]
|
||||
classes[chroma.LineTableTD] = "vertical-align: top; padding: 0; margin: 0; border: 0;" + classes[chroma.LineTableTD]
|
||||
classes[chroma.LineLink] = "outline: none; text-decoration: none; color: inherit" + classes[chroma.LineLink]
|
||||
return classes
|
||||
}
|
||||
|
||||
|
||||
+12
-6
@@ -1,19 +1,24 @@
|
||||
# Lexer tests
|
||||
# Chroma lexers
|
||||
|
||||
All lexers in Chroma should now be defined in XML unless they require custom code.
|
||||
|
||||
## Lexer tests
|
||||
|
||||
The tests in this directory feed a known input `testdata/<name>.actual` into the parser for `<name>` and check
|
||||
that its output matches `<name>.exported`.
|
||||
that its output matches `<name>.expected`.
|
||||
|
||||
It is also possible to perform several tests on a same parser `<name>`, by placing know inputs `*.actual` into a
|
||||
directory `testdata/<name>/`.
|
||||
|
||||
## Running the tests
|
||||
### Running the tests
|
||||
|
||||
Run the tests as normal:
|
||||
```go
|
||||
go test ./lexers
|
||||
```
|
||||
|
||||
## Update existing tests
|
||||
### Update existing tests
|
||||
|
||||
When you add a new test data file (`*.actual`), you need to regenerate all tests. That's how Chroma creates the `*.expected` test file based on the corresponding lexer.
|
||||
|
||||
To regenerate all tests, type in your terminal:
|
||||
@@ -26,7 +31,8 @@ This first sets the `RECORD` environment variable to `true`. Then it runs `go te
|
||||
|
||||
(That environment variable tells Chroma it needs to output test data. After running `go test ./lexers` you can remove or reset that variable.)
|
||||
|
||||
### Windows users
|
||||
#### Windows users
|
||||
|
||||
Windows users will find that the `RECORD=true go test ./lexers` command fails in both the standard command prompt terminal and in PowerShell.
|
||||
|
||||
Instead we have to perform both steps separately:
|
||||
@@ -35,6 +41,6 @@ Instead we have to perform both steps separately:
|
||||
+ In the regular command prompt window, the `set` command sets an environment variable for the current session: `set RECORD=true`. See [this page](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line) for more.
|
||||
+ In PowerShell, you can use the `$env:RECORD = 'true'` command for that. See [this article](https://mcpmag.com/articles/2019/03/28/environment-variables-in-powershell.aspx) for more.
|
||||
+ You can also make a persistent environment variable by hand in the Windows computer settings. See [this article](https://www.computerhope.com/issues/ch000549.htm) for how.
|
||||
- When the environment variable is set, run `go tests ./lexers`.
|
||||
- When the environment variable is set, run `go test ./lexers`.
|
||||
|
||||
Chroma will now regenerate the test files and print its results to the console window.
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package lexers
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma/v2" // nolint
|
||||
)
|
||||
|
||||
// BashSession lexer.
|
||||
var BashSession = Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "BashSession",
|
||||
Aliases: []string{"bash-session", "console", "shell-session"},
|
||||
Filenames: []string{".sh-session"},
|
||||
MimeTypes: []string{"text/x-sh"},
|
||||
EnsureNL: true,
|
||||
},
|
||||
bashsessionRules,
|
||||
))
|
||||
|
||||
func bashsessionRules() Rules {
|
||||
return Rules{
|
||||
"root": {
|
||||
{`^((?:\[[^]]+@[^]]+\]\s?)?[#$%>])(\s*)(.*\n?)`, ByGroups(GenericPrompt, Text, Using("Bash")), nil},
|
||||
{`^.+\n?`, GenericOutput, nil},
|
||||
},
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>ArangoDB AQL</name>
|
||||
<alias>aql</alias>
|
||||
<filename>*.aql</filename>
|
||||
<mime_type>text/x-aql</mime_type>
|
||||
<dot_all>true</dot_all>
|
||||
<ensure_nl>true</ensure_nl>
|
||||
<case_insensitive>true</case_insensitive>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="comments-and-whitespace">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="//.*?\n">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern="/\*">
|
||||
<token type="CommentMultiline"/>
|
||||
<push state="multiline-comment"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="multiline-comment">
|
||||
<rule pattern="[^*]+">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="\*/">
|
||||
<token type="CommentMultiline"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\*">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="double-quote">
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringDouble"/>
|
||||
</rule>
|
||||
<rule pattern="[^"\\]+">
|
||||
<token type="LiteralStringDouble"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralStringDouble"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="single-quote">
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="[^'\\]+">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="LiteralStringSingle"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="backtick">
|
||||
<rule pattern="\\.">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="[^`\\]+">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="`">
|
||||
<token type="Name"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="forwardtick">
|
||||
<rule pattern="\\.">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="[^´\\]+">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="´">
|
||||
<token type="Name"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="identifier">
|
||||
<rule pattern="(?:\$?|_+)[a-z]+[_a-z0-9]*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="`">
|
||||
<token type="Name"/>
|
||||
<push state="backtick"/>
|
||||
</rule>
|
||||
<rule pattern="´">
|
||||
<token type="Name"/>
|
||||
<push state="forwardtick"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule>
|
||||
<include state="comments-and-whitespace"/>
|
||||
</rule>
|
||||
<rule pattern="0b[01]+">
|
||||
<token type="LiteralNumberBin"/>
|
||||
</rule>
|
||||
<rule pattern="0x[0-9a-f]+">
|
||||
<token type="LiteralNumberHex"/>
|
||||
</rule>
|
||||
<rule pattern="(?:0|[1-9][0-9]*)(?![\.e])">
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</rule>
|
||||
<rule pattern="(?:(?:0|[1-9][0-9]*)(?:\.[0-9]+)?|\.[0-9]+)(?:e[\-\+]?[0-9]+)?">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="@@(?:_+[a-z0-9]+[a-z0-9_]*|[a-z0-9][a-z0-9_]*)">
|
||||
<token type="NameVariableGlobal"/>
|
||||
</rule>
|
||||
<rule pattern="@(?:_+[a-z0-9]+[a-z0-9_]*|[a-z0-9][a-z0-9_]*)">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="=~|!~|[=!<>]=?|[%?:/*+-]|\.\.|&&|\|\|">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[.,(){}\[\]]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="[a-zA-Z0-9][a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]+)+(?=\s*\()">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="(WITH)(\s+)(COUNT)(\s+)(INTO)\b">
|
||||
<bygroups>
|
||||
<token type="KeywordReserved"/>
|
||||
<token type="Text"/>
|
||||
<token type="KeywordPseudo"/>
|
||||
<token type="Text"/>
|
||||
<token type="KeywordReserved"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(?:KEEP|PRUNE|SEARCH|TO)\b">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="OPTIONS(?=\s*\{)">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="(?:AGGREGATE|ALL|ALL_SHORTEST_PATHS|AND|ANY|ASC|AT LEAST|COLLECT|DESC|DISTINCT|FILTER|FOR|GRAPH|IN|INBOUND|INSERT|INTO|K_PATHS|K_SHORTEST_PATHS|LIKE|LIMIT|NONE|NOT|OR|OUTBOUND|REMOVE|REPLACE|RETURN|SHORTEST_PATH|SORT|UPDATE|UPSERT|WITH|WINDOW)\b">
|
||||
<token type="KeywordReserved"/>
|
||||
</rule>
|
||||
<rule pattern="LET\b">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="(?:true|false|null)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="(?-i)(?:CURRENT|NEW|OLD)\b">
|
||||
<token type="NameBuiltinPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="(?:to_bool|to_number|to_string|to_array|to_list|is_null|is_bool|is_number|is_string|is_array|is_list|is_object|is_document|is_datestring|typename|json_stringify|json_parse|concat|concat_separator|char_length|lower|upper|substring|substring_bytes|left|right|trim|reverse|contains|log|log2|log10|exp|exp2|sin|cos|tan|asin|acos|atan|atan2|radians|degrees|pi|regex_test|regex_replace|like|floor|ceil|round|abs|rand|sqrt|pow|length|count|min|max|average|avg|sum|product|median|variance_population|variance_sample|variance|percentile|bit_and|bit_or|bit_xor|bit_negate|bit_test|bit_popcount|bit_shift_left|bit_shift_right|bit_construct|bit_deconstruct|bit_to_string|bit_from_string|first|last|unique|outersection|interleave|in_range|jaccard|matches|merge|merge_recursive|has|attributes|keys|values|unset|unset_recursive|keep|keep_recursive|near|within|within_rectangle|is_in_polygon|distance|fulltext|stddev_sample|stddev_population|stddev|slice|nth|position|contains_array|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value|remove_values|remove_nth|replace_nth|date_now|date_timestamp|date_iso8601|date_dayofweek|date_year|date_month|date_day|date_hour|date_minute|date_second|date_millisecond|date_dayofyear|date_isoweek|date_isoweekyear|date_leapyear|date_quarter|date_days_in_month|date_trunc|date_round|date_add|date_subtract|date_diff|date_compare|date_format|date_utctolocal|date_localtoutc|date_timezone|date_timezones|fail|passthru|v8|sleep|schema_get|schema_validate|shard_id|version|noopt|noeval|not_null|first_list|first_document|parse_identifier|current_user|current_database|collection_count|pregel_result|collections|document|decode_rev|range|union|union_distinct|minus|intersection|flatten|is_same_collection|check_document|ltrim|rtrim|find_first|find_last|split|substitute|ipv4_to_number|ipv4_from_number|is_ipv4|md5|sha1|sha256|sha512|crc32|fnv64|hash|random_token|to_base64|to_hex|encode_uri_component|soundex|assert|warn|is_key|sorted|sorted_unique|count_distinct|count_unique|levenshtein_distance|levenshtein_match|regex_matches|regex_split|ngram_match|ngram_similarity|ngram_positional_similarity|uuid|tokens|exists|starts_with|phrase|min_match|bm25|tfidf|boost|analyzer|offset_info|value|cosine_similarity|decay_exp|decay_gauss|decay_linear|l1_distance|l2_distance|minhash|minhash_count|minhash_error|minhash_match|geo_point|geo_multipoint|geo_polygon|geo_multipolygon|geo_linestring|geo_multilinestring|geo_contains|geo_intersects|geo_equals|geo_distance|geo_area|geo_in_range)(?=\s*\()">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralStringDouble"/>
|
||||
<push state="double-quote"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="LiteralStringSingle"/>
|
||||
<push state="single-quote"/>
|
||||
</rule>
|
||||
<!-- not part of the language but useful for highlighting query explain outputs -->
|
||||
<rule pattern="#\d+\b">
|
||||
<token type="NameLabel"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<include state="identifier"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
<lexer>
|
||||
<config>
|
||||
<name>AutoHotkey</name>
|
||||
<alias>autohotkey</alias>
|
||||
<alias>ahk</alias>
|
||||
<filename>*.ahk</filename>
|
||||
<filename>*.ahkl</filename>
|
||||
<mime_type>text/x-autohotkey</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="^(\s*)(/\*)"><bygroups><token type="Text"/><token type="CommentMultiline"/></bygroups><push state="incomment"/></rule>
|
||||
<rule pattern="^(\s*)(\()"><bygroups><token type="Text"/><token type="Generic"/></bygroups><push state="incontinuation"/></rule>
|
||||
<rule pattern="\s+;.*?$"><token type="CommentSingle"/></rule>
|
||||
<rule pattern="^;.*?$"><token type="CommentSingle"/></rule>
|
||||
<rule pattern="[]{}(),;[]"><token type="Punctuation"/></rule>
|
||||
<rule pattern="(in|is|and|or|not)\b"><token type="OperatorWord"/></rule>
|
||||
<rule pattern="\%[a-zA-Z_#@$][\w#@$]*\%"><token type="NameVariable"/></rule>
|
||||
<rule pattern="!=|==|:=|\.=|<<|>>|[-~+/*%=<>&^|?:!.]"><token type="Operator"/></rule>
|
||||
<rule><include state="commands"/></rule>
|
||||
<rule><include state="labels"/></rule>
|
||||
<rule><include state="builtInFunctions"/></rule>
|
||||
<rule><include state="builtInVariables"/></rule>
|
||||
<rule pattern="""><token type="LiteralString"/><combined state="stringescape" state="dqs"/></rule>
|
||||
<rule><include state="numbers"/></rule>
|
||||
<rule pattern="[a-zA-Z_#@$][\w#@$]*"><token type="Name"/></rule>
|
||||
<rule pattern="\\|\'"><token type="Text"/></rule>
|
||||
<rule pattern="\`([,%`abfnrtv\-+;])"><token type="LiteralStringEscape"/></rule>
|
||||
<rule><include state="garbage"/></rule>
|
||||
</state>
|
||||
<state name="incomment">
|
||||
<rule pattern="^\s*\*/"><token type="CommentMultiline"/><pop depth="1"/></rule>
|
||||
<rule pattern="[^*]+"><token type="CommentMultiline"/></rule>
|
||||
<rule pattern="\*"><token type="CommentMultiline"/></rule>
|
||||
</state>
|
||||
<state name="incontinuation">
|
||||
<rule pattern="^\s*\)"><token type="Generic"/><pop depth="1"/></rule>
|
||||
<rule pattern="[^)]"><token type="Generic"/></rule>
|
||||
<rule pattern="[)]"><token type="Generic"/></rule>
|
||||
</state>
|
||||
<state name="commands">
|
||||
<rule pattern="(?i)^(\s*)(global|local|static|#AllowSameLineComments|#ClipboardTimeout|#CommentFlag|#ErrorStdOut|#EscapeChar|#HotkeyInterval|#HotkeyModifierTimeout|#Hotstring|#IfWinActive|#IfWinExist|#IfWinNotActive|#IfWinNotExist|#IncludeAgain|#Include|#InstallKeybdHook|#InstallMouseHook|#KeyHistory|#LTrim|#MaxHotkeysPerInterval|#MaxMem|#MaxThreads|#MaxThreadsBuffer|#MaxThreadsPerHotkey|#NoEnv|#NoTrayIcon|#Persistent|#SingleInstance|#UseHook|#WinActivateForce|AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGetFocus|ControlGetPos|ControlGetText|ControlGet|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|Edit|Else|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|IfEqual|IfExist|IfGreaterOrEqual|IfGreater|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|If |ImageSearch|IniDelete|IniRead|IniWrite|InputBox|Input|KeyHistory|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClickDrag|MouseClick|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|RunAs|RunWait|Run|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|Send|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|While|WinActivate|WinActivateBottom|WinClose|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinGet|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimizeAllUndo|WinMinimizeAll|WinMinimize|WinMove|WinRestore|WinSetTitle|WinSet|WinShow|WinWaitActive|WinWaitClose|WinWaitNotActive|WinWait)\b"><bygroups><token type="Text"/><token type="NameBuiltin"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="builtInFunctions">
|
||||
<rule pattern="(?i)(Abs|ACos|Asc|ASin|ATan|Ceil|Chr|Cos|DllCall|Exp|FileExist|Floor|GetKeyState|IL_Add|IL_Create|IL_Destroy|InStr|IsFunc|IsLabel|Ln|Log|LV_Add|LV_Delete|LV_DeleteCol|LV_GetCount|LV_GetNext|LV_GetText|LV_Insert|LV_InsertCol|LV_Modify|LV_ModifyCol|LV_SetImageList|Mod|NumGet|NumPut|OnMessage|RegExMatch|RegExReplace|RegisterCallback|Round|SB_SetIcon|SB_SetParts|SB_SetText|Sin|Sqrt|StrLen|SubStr|Tan|TV_Add|TV_Delete|TV_GetChild|TV_GetCount|TV_GetNext|TV_Get|TV_GetParent|TV_GetPrev|TV_GetSelection|TV_GetText|TV_Modify|VarSetCapacity|WinActive|WinExist|Object|ComObjActive|ComObjArray|ComObjEnwrap|ComObjUnwrap|ComObjParameter|ComObjType|ComObjConnect|ComObjCreate|ComObjGet|ComObjError|ComObjValue|Insert|MinIndex|MaxIndex|Remove|SetCapacity|GetCapacity|GetAddress|_NewEnum|FileOpen|Read|Write|ReadLine|WriteLine|ReadNumType|WriteNumType|RawRead|RawWrite|Seek|Tell|Close|Next|IsObject|StrPut|StrGet|Trim|LTrim|RTrim)\b"><token type="NameFunction"/></rule>
|
||||
</state>
|
||||
<state name="builtInVariables">
|
||||
<rule pattern="(?i)(A_AhkPath|A_AhkVersion|A_AppData|A_AppDataCommon|A_AutoTrim|A_BatchLines|A_CaretX|A_CaretY|A_ComputerName|A_ControlDelay|A_Cursor|A_DDDD|A_DDD|A_DD|A_DefaultMouseSpeed|A_Desktop|A_DesktopCommon|A_DetectHiddenText|A_DetectHiddenWindows|A_EndChar|A_EventInfo|A_ExitReason|A_FormatFloat|A_FormatInteger|A_Gui|A_GuiEvent|A_GuiControl|A_GuiControlEvent|A_GuiHeight|A_GuiWidth|A_GuiX|A_GuiY|A_Hour|A_IconFile|A_IconHidden|A_IconNumber|A_IconTip|A_Index|A_IPAddress1|A_IPAddress2|A_IPAddress3|A_IPAddress4|A_ISAdmin|A_IsCompiled|A_IsCritical|A_IsPaused|A_IsSuspended|A_KeyDelay|A_Language|A_LastError|A_LineFile|A_LineNumber|A_LoopField|A_LoopFileAttrib|A_LoopFileDir|A_LoopFileExt|A_LoopFileFullPath|A_LoopFileLongPath|A_LoopFileName|A_LoopFileShortName|A_LoopFileShortPath|A_LoopFileSize|A_LoopFileSizeKB|A_LoopFileSizeMB|A_LoopFileTimeAccessed|A_LoopFileTimeCreated|A_LoopFileTimeModified|A_LoopReadLine|A_LoopRegKey|A_LoopRegName|A_LoopRegSubkey|A_LoopRegTimeModified|A_LoopRegType|A_MDAY|A_Min|A_MM|A_MMM|A_MMMM|A_Mon|A_MouseDelay|A_MSec|A_MyDocuments|A_Now|A_NowUTC|A_NumBatchLines|A_OSType|A_OSVersion|A_PriorHotkey|A_ProgramFiles|A_Programs|A_ProgramsCommon|A_ScreenHeight|A_ScreenWidth|A_ScriptDir|A_ScriptFullPath|A_ScriptName|A_Sec|A_Space|A_StartMenu|A_StartMenuCommon|A_Startup|A_StartupCommon|A_StringCaseSense|A_Tab|A_Temp|A_ThisFunc|A_ThisHotkey|A_ThisLabel|A_ThisMenu|A_ThisMenuItem|A_ThisMenuItemPos|A_TickCount|A_TimeIdle|A_TimeIdlePhysical|A_TimeSincePriorHotkey|A_TimeSinceThisHotkey|A_TitleMatchMode|A_TitleMatchModeSpeed|A_UserName|A_WDay|A_WinDelay|A_WinDir|A_WorkingDir|A_YDay|A_YEAR|A_YWeek|A_YYYY|Clipboard|ClipboardAll|ComSpec|ErrorLevel|ProgramFiles|True|False|A_IsUnicode|A_FileEncoding|A_OSVersion|A_PtrSize)\b"><token type="NameVariable"/></rule>
|
||||
</state>
|
||||
<state name="labels">
|
||||
<rule pattern="(^\s*)([^:\s("]+?:{1,2})"><bygroups><token type="Text"/><token type="NameLabel"/></bygroups></rule>
|
||||
<rule pattern="(^\s*)(::[^:\s]+?::)"><bygroups><token type="Text"/><token type="NameLabel"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="numbers">
|
||||
<rule pattern="(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?"><token type="LiteralNumberFloat"/></rule>
|
||||
<rule pattern="\d+[eE][+-]?[0-9]+"><token type="LiteralNumberFloat"/></rule>
|
||||
<rule pattern="0\d+"><token type="LiteralNumberOct"/></rule>
|
||||
<rule pattern="0[xX][a-fA-F0-9]+"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern="\d+L"><token type="LiteralNumberIntegerLong"/></rule>
|
||||
<rule pattern="\d+"><token type="LiteralNumberInteger"/></rule>
|
||||
</state>
|
||||
<state name="stringescape">
|
||||
<rule pattern="\"\"|\`([,%`abfnrtv])"><token type="LiteralStringEscape"/></rule>
|
||||
</state>
|
||||
<state name="strings">
|
||||
<rule pattern="[^"\n]+"><token type="LiteralString"/></rule>
|
||||
</state>
|
||||
<state name="dqs">
|
||||
<rule pattern="""><token type="LiteralString"/><pop depth="1"/></rule>
|
||||
<rule><include state="strings"/></rule>
|
||||
</state>
|
||||
<state name="garbage">
|
||||
<rule pattern="[^\S\n]"><token type="Text"/></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
|
||||
+70
File diff suppressed because one or more lines are too long
+25
@@ -0,0 +1,25 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>BashSession</name>
|
||||
<alias>bash-session</alias>
|
||||
<alias>console</alias>
|
||||
<alias>shell-session</alias>
|
||||
<filename>*.sh-session</filename>
|
||||
<mime_type>text/x-sh</mime_type>
|
||||
<ensure_nl>true</ensure_nl>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="^((?:\[[^]]+@[^]]+\]\s?)?[#$%>])(\s*)(.*\n?)">
|
||||
<bygroups>
|
||||
<token type="GenericPrompt"/>
|
||||
<token type="Text"/>
|
||||
<using lexer="bash"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="^.+\n?">
|
||||
<token type="GenericOutput"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>BQN</name>
|
||||
<alias>bqn</alias>
|
||||
<filename>*.bqn</filename>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="\s+">
|
||||
<token type="TextWhitespace"/>
|
||||
</rule>
|
||||
<rule pattern="\A#!.+$">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="#.*$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern=""(?:[^"]|"")*"">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="[{}]">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="[⟨⟩\[\]‿]">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="[()]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="[:;?]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="[⋄,]">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="[←⇐↩→]">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="'.'">
|
||||
<token type="LiteralStringChar"/>
|
||||
</rule>
|
||||
<rule pattern="[˙˜˘¨⌜⁼´˝`]">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[∘○⊸⟜⌾⊘◶⎉⚇⍟⎊]">
|
||||
<token type="OperatorWord"/>
|
||||
</rule>
|
||||
<rule pattern="[𝔽𝔾𝕎𝕏𝕊+\-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍⋈↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!⍕⍎]">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="[𝕗𝕘𝕨𝕩𝕤]">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="·">
|
||||
<token type="NameConstant"/>
|
||||
</rule>
|
||||
<rule pattern="@">
|
||||
<token type="LiteralStringChar"/>
|
||||
</rule>
|
||||
<rule pattern="\d+(?:\.\d+)?[eE]¯?\d+">
|
||||
<token type="LiteralNumber"/>
|
||||
</rule>
|
||||
<rule pattern="[¯∞π]?(?:\d*\.?\b\d+(?:e[+¯]?\d+|E[+¯]?\d+)?|¯|∞|π)(?:j¯?(?:(?:\d+(?:\.\d+)?|\.\d+)(?:e[+¯]?\d+|E[+¯]?\d+)?|¯|∞|π))?">
|
||||
<token type="LiteralNumber"/>
|
||||
</rule>
|
||||
<rule pattern="(•?[a-z][A-Z_a-z0-9π∞¯]*|𝕣)">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="•?[A-Z][A-Z_a-z0-9π∞¯]*">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="(•?_[A-Za-z][A-Z_a-z0-9π∞¯]*|_𝕣)">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="(•?_[A-Za-z][A-Z_a-z0-9π∞¯]*_|_𝕣_)">
|
||||
<token type="OperatorWord"/>
|
||||
</rule>
|
||||
<rule pattern="\.">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+5
-2
@@ -196,7 +196,7 @@
|
||||
<rule pattern="(restricted|volatile|continue|register|default|typedef|struct|extern|switch|sizeof|static|return|union|while|const|break|goto|enum|else|case|auto|for|asm|if|do)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(bool|int|long|float|short|double|char((8|16|32)_t)?|unsigned|signed|void|u?int(_fast|_least|)(8|16|32|64)_t)\b">
|
||||
<rule pattern="(bool|int|long|float|short|double|char((8|16|32)_t)?|unsigned|signed|void|u?int(_fast|_least|)(8|16|32|64)_t)\b|\b[a-z]\w*_t\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="(typename|__inline|restrict|_inline|thread|inline|naked)\b">
|
||||
@@ -218,6 +218,9 @@
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\b[A-Za-z_]\w*(?=\s*\()">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="[a-zA-Z_]\w*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
@@ -250,4 +253,4 @@
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
</lexer>
|
||||
|
||||
+10
-7
@@ -38,7 +38,7 @@
|
||||
<rule pattern="#.*?\n">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
<rule pattern="@.*?\n">
|
||||
<rule pattern="^@.*?\n">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="(body)(\s+)(\S+)(\s+)(control)">
|
||||
@@ -78,6 +78,12 @@
|
||||
<token type="Text"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="([\w.!&|()"$]+)(::)">
|
||||
<bygroups>
|
||||
<token type="NameClass"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="doublequotestring"/>
|
||||
@@ -96,12 +102,6 @@
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="([\w.!&|()]+)(::)">
|
||||
<bygroups>
|
||||
<token type="NameClass"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(\w+)(:)">
|
||||
<bygroups>
|
||||
<token type="KeywordDeclaration"/>
|
||||
@@ -111,6 +111,9 @@
|
||||
<rule pattern="@[{(][^)}]+[})]">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="\$[(][^)]+[)]">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="[(){},;]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+6
-3
@@ -21,7 +21,7 @@
|
||||
<rule pattern="/\+.*?\+/">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="(asm|assert|body|break|case|cast|catch|continue|default|debug|delete|deprecated|do|else|finally|for|foreach|foreach_reverse|goto|if|in|invariant|is|macro|mixin|new|out|pragma|return|super|switch|this|throw|try|version|while|with)\b">
|
||||
<rule pattern="(asm|assert|body|break|case|cast|catch|continue|default|debug|delete|do|else|finally|for|foreach|foreach_reverse|goto|if|in|invariant|is|macro|mixin|new|out|pragma|return|super|switch|this|throw|try|typeid|typeof|version|while|with)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="__(FILE|FILE_FULL_PATH|MODULE|LINE|FUNCTION|PRETTY_FUNCTION|DATE|EOF|TIME|TIMESTAMP|VENDOR|VERSION)__\b">
|
||||
@@ -41,12 +41,15 @@
|
||||
<rule pattern="@[\w.]*">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="(abstract|auto|alias|align|const|delegate|enum|export|final|function|inout|lazy|nothrow|override|package|private|protected|public|pure|static|synchronized|template|volatile|__gshared)\b">
|
||||
<rule pattern="(abstract|auto|alias|align|const|delegate|deprecated|enum|export|extern|final|function|immutable|inout|lazy|nothrow|override|package|private|protected|public|pure|ref|scope|shared|static|synchronized|template|unittest|__gshared)\b">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="(void|bool|byte|ubyte|short|ushort|int|uint|long|ulong|cent|ucent|float|double|real|ifloat|idouble|ireal|cfloat|cdouble|creal|char|wchar|dchar|string|wstring|dstring)\b">
|
||||
<rule pattern="(void|bool|byte|ubyte|short|ushort|int|uint|long|ulong|cent|ucent|float|double|real|ifloat|idouble|ireal|cfloat|cdouble|creal|char|wchar|dchar)\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="(size_t|ptrdiff_t|noreturn|string|wstring|dstring|Object|Throwable|Exception|Error|imported)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="(module)(\s+)">
|
||||
<bygroups>
|
||||
<token type="KeywordNamespace"/>
|
||||
|
||||
+12
@@ -14,6 +14,18 @@
|
||||
<rule pattern=" .*\n">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\d+(,\d+)?(a|c|d)\d+(,\d+)?\n">
|
||||
<token type="GenericSubheading"/>
|
||||
</rule>
|
||||
<rule pattern="---\n">
|
||||
<token type="GenericStrong"/>
|
||||
</rule>
|
||||
<rule pattern="< .*\n">
|
||||
<token type="GenericDeleted"/>
|
||||
</rule>
|
||||
<rule pattern="> .*\n">
|
||||
<token type="GenericInserted"/>
|
||||
</rule>
|
||||
<rule pattern="\+.*\n">
|
||||
<token type="GenericInserted"/>
|
||||
</rule>
|
||||
|
||||
+14
-6
@@ -15,15 +15,23 @@
|
||||
<rules>
|
||||
<state name="core">
|
||||
<rule pattern="\b(DO)(\s+)(CONCURRENT)\b">
|
||||
<token type="Keyword"/>
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="Keyword"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\b(GO)(\s*)(TO)\b">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="Keyword"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\b(ABSTRACT|ACCEPT|ALL|ALLSTOP|ALLOCATABLE|ALLOCATE|ARRAY|ASSIGN|ASSOCIATE|ASYNCHRONOUS|BACKSPACE|BIND|BLOCK|BLOCKDATA|BYTE|CALL|CASE|CLASS|CLOSE|CODIMENSION|COMMON|CONTIGUOUS|CONTAINS|CONTINUE|CRITICAL|CYCLE|DATA|DEALLOCATE|DECODE|DEFERRED|DIMENSION|DO|ELEMENTAL|ELSE|ENCODE|END|ENDASSOCIATE|ENDBLOCK|ENDDO|ENDENUM|ENDFORALL|ENDFUNCTION|ENDIF|ENDINTERFACE|ENDMODULE|ENDPROGRAM|ENDSELECT|ENDSUBMODULE|ENDSUBROUTINE|ENDTYPE|ENDWHERE|ENTRY|ENUM|ENUMERATOR|EQUIVALENCE|ERROR STOP|EXIT|EXTENDS|EXTERNAL|EXTRINSIC|FILE|FINAL|FORALL|FORMAT|FUNCTION|GENERIC|IF|IMAGES|IMPLICIT|IMPORT|IMPURE|INCLUDE|INQUIRE|INTENT|INTERFACE|INTRINSIC|IS|LOCK|MEMORY|MODULE|NAMELIST|NULLIFY|NONE|NON_INTRINSIC|NON_OVERRIDABLE|NOPASS|ONLY|OPEN|OPTIONAL|OPTIONS|PARAMETER|PASS|PAUSE|POINTER|PRINT|PRIVATE|PROGRAM|PROCEDURE|PROTECTED|PUBLIC|PURE|READ|RECURSIVE|RESULT|RETURN|REWIND|SAVE|SELECT|SEQUENCE|STOP|SUBMODULE|SUBROUTINE|SYNC|SYNCALL|SYNCIMAGES|SYNCMEMORY|TARGET|THEN|TYPE|UNLOCK|USE|VALUE|VOLATILE|WHERE|WRITE|WHILE)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\b(ABSTRACT|ACCEPT|ALL|ALLSTOP|ALLOCATABLE|ALLOCATE|ARRAY|ASSIGN|ASSOCIATE|ASYNCHRONOUS|BACKSPACE|BIND|BLOCK|BLOCKDATA|BYTE|CALL|CASE|CLASS|CLOSE|CODIMENSION|COMMON|CONTIGUOUS|CONTAINS|CONTINUE|CRITICAL|CYCLE|DATA|DEALLOCATE|DECODE|DEFERRED|DIMENSION|DO|ELEMENTAL|ELSE|ENCODE|END|ENDASSOCIATE|ENDBLOCK|ENDDO|ENDENUM|ENDFORALL|ENDFUNCTION|ENDIF|ENDINTERFACE|ENDMODULE|ENDPROGRAM|ENDSELECT|ENDSUBMODULE|ENDSUBROUTINE|ENDTYPE|ENDWHERE|ENTRY|ENUM|ENUMERATOR|EQUIVALENCE|ERROR STOP|EXIT|EXTENDS|EXTERNAL|EXTRINSIC|FILE|FINAL|FORALL|FORMAT|FUNCTION|GENERIC|IF|IMAGES|IMPLICIT|IMPORT|IMPURE|INCLUDE|INQUIRE|INTENT|INTERFACE|INTRINSIC|IS|LOCK|MEMORY|MODULE|NAMELIST|NULLIFY|NONE|NON_INTRINSIC|NON_OVERRIDABLE|NOPASS|ONLY|OPEN|OPTIONAL|OPTIONS|PARAMETER|PASS|PAUSE|POINTER|PRINT|PRIVATE|PROGRAM|PROCEDURE|PROTECTED|PUBLIC|PURE|READ|RECURSIVE|RESULT|RETURN|REWIND|SAVE|SELECT|SEQUENCE|STOP|SUBMODULE|SUBROUTINE|SYNC|SYNCALL|SYNCIMAGES|SYNCMEMORY|TARGET|THEN|TYPE|UNLOCK|USE|VALUE|VOLATILE|WHERE|WRITE|WHILE)\s*\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\b(CHARACTER|COMPLEX|DOUBLE PRECISION|DOUBLE COMPLEX|INTEGER|LOGICAL|REAL|C_INT|C_SHORT|C_LONG|C_LONG_LONG|C_SIGNED_CHAR|C_SIZE_T|C_INT8_T|C_INT16_T|C_INT32_T|C_INT64_T|C_INT_LEAST8_T|C_INT_LEAST16_T|C_INT_LEAST32_T|C_INT_LEAST64_T|C_INT_FAST8_T|C_INT_FAST16_T|C_INT_FAST32_T|C_INT_FAST64_T|C_INTMAX_T|C_INTPTR_T|C_FLOAT|C_DOUBLE|C_LONG_DOUBLE|C_FLOAT_COMPLEX|C_DOUBLE_COMPLEX|C_LONG_DOUBLE_COMPLEX|C_BOOL|C_CHAR|C_PTR|C_FUNPTR)\s*\b">
|
||||
<rule pattern="\b(CHARACTER|COMPLEX|DOUBLE PRECISION|DOUBLE COMPLEX|INTEGER|LOGICAL|REAL|C_INT|C_SHORT|C_LONG|C_LONG_LONG|C_SIGNED_CHAR|C_SIZE_T|C_INT8_T|C_INT16_T|C_INT32_T|C_INT64_T|C_INT_LEAST8_T|C_INT_LEAST16_T|C_INT_LEAST32_T|C_INT_LEAST64_T|C_INT_FAST8_T|C_INT_FAST16_T|C_INT_FAST32_T|C_INT_FAST64_T|C_INTMAX_T|C_INTPTR_T|C_FLOAT|C_DOUBLE|C_LONG_DOUBLE|C_FLOAT_COMPLEX|C_DOUBLE_COMPLEX|C_LONG_DOUBLE_COMPLEX|C_BOOL|C_CHAR|C_PTR|C_FUNPTR)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(\*\*|\*|\+|-|\/|<|>|<=|>=|==|\/=|=)">
|
||||
@@ -35,7 +43,7 @@
|
||||
<rule pattern="[()\[\],:&%;.]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="\b(Abort|Abs|Access|AChar|ACos|ACosH|AdjustL|AdjustR|AImag|AInt|Alarm|All|Allocated|ALog|AMax|AMin|AMod|And|ANInt|Any|ASin|ASinH|Associated|ATan|ATanH|Atomic_Define|Atomic_Ref|BesJ|BesJN|Bessel_J0|Bessel_J1|Bessel_JN|Bessel_Y0|Bessel_Y1|Bessel_YN|BesY|BesYN|BGE|BGT|BLE|BLT|Bit_Size|BTest|CAbs|CCos|Ceiling|CExp|Char|ChDir|ChMod|CLog|Cmplx|Command_Argument_Count|Complex|Conjg|Cos|CosH|Count|CPU_Time|CShift|CSin|CSqRt|CTime|C_Loc|C_Associated|C_Null_Ptr|C_Null_Funptr|C_F_Pointer|C_F_ProcPointer|C_Null_Char|C_Alert|C_Backspace|C_Form_Feed|C_FunLoc|C_Sizeof|C_New_Line|C_Carriage_Return|C_Horizontal_Tab|C_Vertical_Tab|DAbs|DACos|DASin|DATan|Date_and_Time|DbesJ|DbesJN|DbesY|DbesYN|Dble|DCos|DCosH|DDiM|DErF|DErFC|DExp|Digits|DiM|DInt|DLog|DMax|DMin|DMod|DNInt|Dot_Product|DProd|DSign|DSinH|DShiftL|DShiftR|DSin|DSqRt|DTanH|DTan|DTime|EOShift|Epsilon|ErF|ErFC|ErFC_Scaled|ETime|Execute_Command_Line|Exit|Exp|Exponent|Extends_Type_Of|FDate|FGet|FGetC|FindLoc|Float|Floor|Flush|FNum|FPutC|FPut|Fraction|FSeek|FStat|FTell|Gamma|GError|GetArg|Get_Command|Get_Command_Argument|Get_Environment_Variable|GetCWD|GetEnv|GetGId|GetLog|GetPId|GetUId|GMTime|HostNm|Huge|Hypot|IAbs|IAChar|IAll|IAnd|IAny|IArgC|IBClr|IBits|IBSet|IChar|IDate|IDiM|IDInt|IDNInt|IEOr|IErrNo|IFix|Imag|ImagPart|Image_Index|Index|Int|IOr|IParity|IRand|IsaTty|IShft|IShftC|ISign|Iso_C_Binding|Is_Contiguous|Is_Iostat_End|Is_Iostat_Eor|ITime|Kill|Kind|LBound|LCoBound|Len|Len_Trim|LGe|LGt|Link|LLe|LLt|LnBlnk|Loc|Log|Log_Gamma|Logical|Long|LShift|LStat|LTime|MaskL|MaskR|MatMul|Max|MaxExponent|MaxLoc|MaxVal|MClock|Merge|Merge_Bits|Move_Alloc|Min|MinExponent|MinLoc|MinVal|Mod|Modulo|MvBits|Nearest|New_Line|NInt|Norm2|Not|Null|Num_Images|Or|Pack|Parity|PError|Precision|Present|Product|Radix|Rand|Random_Number|Random_Seed|Range|Real|RealPart|Rename|Repeat|Reshape|RRSpacing|RShift|Same_Type_As|Scale|Scan|Second|Selected_Char_Kind|Selected_Int_Kind|Selected_Real_Kind|Set_Exponent|Shape|ShiftA|ShiftL|ShiftR|Short|Sign|Signal|SinH|Sin|Sleep|Sngl|Spacing|Spread|SqRt|SRand|Stat|Storage_Size|Sum|SymLnk|System|System_Clock|Tan|TanH|Time|This_Image|Tiny|TrailZ|Transfer|Transpose|Trim|TtyNam|UBound|UCoBound|UMask|Unlink|Unpack|Verify|XOr|ZAbs|ZCos|ZExp|ZLog|ZSin|ZSqRt)\s*\b">
|
||||
<rule pattern="\b(Abort|Abs|Access|AChar|ACos|ACosH|AdjustL|AdjustR|AImag|AInt|Alarm|All|Allocated|ALog|AMax|AMin|AMod|And|ANInt|Any|ASin|ASinH|Associated|ATan|ATanH|Atomic_Define|Atomic_Ref|BesJ|BesJN|Bessel_J0|Bessel_J1|Bessel_JN|Bessel_Y0|Bessel_Y1|Bessel_YN|BesY|BesYN|BGE|BGT|BLE|BLT|Bit_Size|BTest|CAbs|CCos|Ceiling|CExp|Char|ChDir|ChMod|CLog|Cmplx|Command_Argument_Count|Complex|Conjg|Cos|CosH|Count|CPU_Time|CShift|CSin|CSqRt|CTime|C_Loc|C_Associated|C_Null_Ptr|C_Null_Funptr|C_F_Pointer|C_F_ProcPointer|C_Null_Char|C_Alert|C_Backspace|C_Form_Feed|C_FunLoc|C_Sizeof|C_New_Line|C_Carriage_Return|C_Horizontal_Tab|C_Vertical_Tab|DAbs|DACos|DASin|DATan|Date_and_Time|DbesJ|DbesJN|DbesY|DbesYN|Dble|DCos|DCosH|DDiM|DErF|DErFC|DExp|Digits|DiM|DInt|DLog|DMax|DMin|DMod|DNInt|Dot_Product|DProd|DSign|DSinH|DShiftL|DShiftR|DSin|DSqRt|DTanH|DTan|DTime|EOShift|Epsilon|ErF|ErFC|ErFC_Scaled|ETime|Execute_Command_Line|Exit|Exp|Exponent|Extends_Type_Of|FDate|FGet|FGetC|FindLoc|Float|Floor|Flush|FNum|FPutC|FPut|Fraction|FSeek|FStat|FTell|Gamma|GError|GetArg|Get_Command|Get_Command_Argument|Get_Environment_Variable|GetCWD|GetEnv|GetGId|GetLog|GetPId|GetUId|GMTime|HostNm|Huge|Hypot|IAbs|IAChar|IAll|IAnd|IAny|IArgC|IBClr|IBits|IBSet|IChar|IDate|IDiM|IDInt|IDNInt|IEOr|IErrNo|IFix|Imag|ImagPart|Image_Index|Index|Int|IOr|IParity|IRand|IsaTty|IShft|IShftC|ISign|Iso_C_Binding|Is_Contiguous|Is_Iostat_End|Is_Iostat_Eor|ITime|Kill|Kind|LBound|LCoBound|Len|Len_Trim|LGe|LGt|Link|LLe|LLt|LnBlnk|Loc|Log|Log_Gamma|Logical|Long|LShift|LStat|LTime|MaskL|MaskR|MatMul|Max|MaxExponent|MaxLoc|MaxVal|MClock|Merge|Merge_Bits|Move_Alloc|Min|MinExponent|MinLoc|MinVal|Mod|Modulo|MvBits|Nearest|New_Line|NInt|Norm2|Not|Null|Num_Images|Or|Pack|Parity|PError|Precision|Present|Product|Radix|Rand|Random_Number|Random_Seed|Range|Real|RealPart|Rename|Repeat|Reshape|RRSpacing|RShift|Same_Type_As|Scale|Scan|Second|Selected_Char_Kind|Selected_Int_Kind|Selected_Real_Kind|Set_Exponent|Shape|ShiftA|ShiftL|ShiftR|Short|Sign|Signal|SinH|Sin|Sleep|Sngl|Spacing|Spread|SqRt|SRand|Stat|Storage_Size|Sum|SymLnk|System|System_Clock|Tan|TanH|Time|This_Image|Tiny|TrailZ|Transfer|Transpose|Trim|TtyNam|UBound|UCoBound|UMask|Unlink|Unpack|Verify|XOr|ZAbs|ZCos|ZExp|ZLog|ZSin|ZSqRt)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="\.(true|false)\.">
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@
|
||||
<token type="LiteralString"/>
|
||||
<push state="string"/>
|
||||
</rule>
|
||||
<rule pattern="\b(open|module)(\s+)([\w.]+)">
|
||||
<rule pattern="\b(open type|open|module)(\s+)([\w.]+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@
|
||||
<token type="Operator"/>
|
||||
<push state="subexpression"/>
|
||||
</rule>
|
||||
<rule pattern="(range|if|else|while|with|template|end|true|false|nil|and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b">
|
||||
<rule pattern="(range|if|else|while|with|template|end|true|false|nil|and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge|block|break|continue|define|slice)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\||:?=|,">
|
||||
@@ -109,4 +109,4 @@
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
</lexer>
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@
|
||||
<rule pattern="(true|false|null)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="(class|interface)(\s+)">
|
||||
<rule pattern="(class|interface|record)(\s+)">
|
||||
<bygroups>
|
||||
<token type="KeywordDeclaration"/>
|
||||
<token type="Text"/>
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>HLSL</name>
|
||||
<alias>hlsl</alias>
|
||||
<filename>*.hlsl</filename>
|
||||
<filename>*.hlsli</filename>
|
||||
<mime_type>text/x-hlsl</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="^#.*$">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="//.*$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern="/(\\\n)?[*](.|\n)*?[*](\\\n)?/">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="\+|-|~|!=?|\*|/|%|<<|>>|<=?|>=?|==?|&&?|\^|\|\|?">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[?:]">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="\bdefined\b">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[;{}(),.\[\]]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="[+-]?\d*\.\d+([eE][-+]?\d+)?f?">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="[+-]?\d+\.\d*([eE][-+]?\d+)?f?">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="0[xX][0-9a-fA-F]*">
|
||||
<token type="LiteralNumberHex"/>
|
||||
</rule>
|
||||
<rule pattern="0[0-7]*">
|
||||
<token type="LiteralNumberOct"/>
|
||||
</rule>
|
||||
<rule pattern="[1-9][0-9]*">
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="string"/>
|
||||
</rule>
|
||||
<rule pattern="\b(asm|asm_fragment|break|case|cbuffer|centroid|class|column_major|compile|compile_fragment|const|continue|default|discard|do|else|export|extern|for|fxgroup|globallycoherent|groupshared|if|in|inline|inout|interface|line|lineadj|linear|namespace|nointerpolation|noperspective|NULL|out|packoffset|pass|pixelfragment|point|precise|return|register|row_major|sample|sampler|shared|stateblock|stateblock_state|static|struct|switch|tbuffer|technique|technique10|technique11|texture|typedef|triangle|triangleadj|uniform|vertexfragment|volatile|while)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\b(true|false)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="\b(auto|catch|char|const_cast|delete|dynamic_cast|enum|explicit|friend|goto|long|mutable|new|operator|private|protected|public|reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try|typename|union|unsigned|using|virtual)\b">
|
||||
<token type="KeywordReserved"/>
|
||||
</rule>
|
||||
<rule pattern="\b(dword|matrix|snorm|string|unorm|unsigned|void|vector|BlendState|Buffer|ByteAddressBuffer|ComputeShader|DepthStencilState|DepthStencilView|DomainShader|GeometryShader|HullShader|InputPatch|LineStream|OutputPatch|PixelShader|PointStream|RasterizerState|RenderTargetView|RasterizerOrderedBuffer|RasterizerOrderedByteAddressBuffer|RasterizerOrderedStructuredBuffer|RasterizerOrderedTexture1D|RasterizerOrderedTexture1DArray|RasterizerOrderedTexture2D|RasterizerOrderedTexture2DArray|RasterizerOrderedTexture3D|RWBuffer|RWByteAddressBuffer|RWStructuredBuffer|RWTexture1D|RWTexture1DArray|RWTexture2D|RWTexture2DArray|RWTexture3D|SamplerState|SamplerComparisonState|StructuredBuffer|Texture1D|Texture1DArray|Texture2D|Texture2DArray|Texture2DMS|Texture2DMSArray|Texture3D|TextureCube|TextureCubeArray|TriangleStream|VertexShader)\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="\b(bool|double|float|int|half|min16float|min10float|min16int|min12int|min16uint|uint)([1-4](x[1-4])?)?\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="\b(abort|abs|acos|all|AllMemoryBarrier|AllMemoryBarrierWithGroupSync|any|AppendStructuredBuffer|asdouble|asfloat|asin|asint|asuint|asuint|atan|atan2|ceil|CheckAccessFullyMapped|clamp|clip|CompileShader|ConsumeStructuredBuffer|cos|cosh|countbits|cross|D3DCOLORtoUBYTE4|ddx|ddx_coarse|ddx_fine|ddy|ddy_coarse|ddy_fine|degrees|determinant|DeviceMemoryBarrier|DeviceMemoryBarrierWithGroupSync|distance|dot|dst|errorf|EvaluateAttributeAtCentroid|EvaluateAttributeAtSample|EvaluateAttributeSnapped|exp|exp2|f16tof32|f32tof16|faceforward|firstbithigh|firstbitlow|floor|fma|fmod|frac|frexp|fwidth|GetRenderTargetSampleCount|GetRenderTargetSamplePosition|GlobalOrderedCountIncrement|GroupMemoryBarrier|GroupMemoryBarrierWithGroupSync|InterlockedAdd|InterlockedAnd|InterlockedCompareExchange|InterlockedCompareStore|InterlockedExchange|InterlockedMax|InterlockedMin|InterlockedOr|InterlockedXor|isfinite|isinf|isnan|ldexp|length|lerp|lit|log|log10|log2|mad|max|min|modf|msad4|mul|noise|normalize|pow|printf|Process2DQuadTessFactorsAvg|Process2DQuadTessFactorsMax|Process2DQuadTessFactorsMin|ProcessIsolineTessFactors|ProcessQuadTessFactorsAvg|ProcessQuadTessFactorsMax|ProcessQuadTessFactorsMin|ProcessTriTessFactorsAvg|ProcessTriTessFactorsMax|ProcessTriTessFactorsMin|QuadReadLaneAt|QuadSwapX|QuadSwapY|radians|rcp|reflect|refract|reversebits|round|rsqrt|saturate|sign|sin|sincos|sinh|smoothstep|sqrt|step|tan|tanh|tex1D|tex1D|tex1Dbias|tex1Dgrad|tex1Dlod|tex1Dproj|tex2D|tex2D|tex2Dbias|tex2Dgrad|tex2Dlod|tex2Dproj|tex3D|tex3D|tex3Dbias|tex3Dgrad|tex3Dlod|tex3Dproj|texCUBE|texCUBE|texCUBEbias|texCUBEgrad|texCUBElod|texCUBEproj|transpose|trunc|WaveAllBitAnd|WaveAllMax|WaveAllMin|WaveAllBitOr|WaveAllBitXor|WaveAllEqual|WaveAllProduct|WaveAllSum|WaveAllTrue|WaveAnyTrue|WaveBallot|WaveGetLaneCount|WaveGetLaneIndex|WaveGetOrderedIndex|WaveIsHelperLane|WaveOnce|WavePrefixProduct|WavePrefixSum|WaveReadFirstLane|WaveReadLaneAt)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="\b(SV_ClipDistance|SV_ClipDistance0|SV_ClipDistance1|SV_Culldistance|SV_CullDistance0|SV_CullDistance1|SV_Coverage|SV_Depth|SV_DepthGreaterEqual|SV_DepthLessEqual|SV_DispatchThreadID|SV_DomainLocation|SV_GroupID|SV_GroupIndex|SV_GroupThreadID|SV_GSInstanceID|SV_InnerCoverage|SV_InsideTessFactor|SV_InstanceID|SV_IsFrontFace|SV_OutputControlPointID|SV_Position|SV_PrimitiveID|SV_RenderTargetArrayIndex|SV_SampleIndex|SV_StencilRef|SV_TessFactor|SV_VertexID|SV_ViewportArrayIndex)\b">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="\bSV_Target[0-7]?\b">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="\b(allow_uav_condition|branch|call|domain|earlydepthstencil|fastopt|flatten|forcecase|instance|loop|maxtessfactor|numthreads|outputcontrolpoints|outputtopology|partitioning|patchconstantfunc|unroll)\b">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="[a-zA-Z_]\w*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="\\$">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"\n]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\\n">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>HolyC</name>
|
||||
<alias>holyc</alias>
|
||||
<filename>*.HC</filename>
|
||||
<filename>*.hc</filename>
|
||||
<filename>*.HH</filename>
|
||||
<filename>*.hh</filename>
|
||||
<filename>*.hc.z</filename>
|
||||
<filename>*.HC.Z</filename>
|
||||
<mime_type>text/x-chdr</mime_type>
|
||||
<mime_type>text/x-csrc</mime_type>
|
||||
<mime_type>image/x-xbitmap</mime_type>
|
||||
<mime_type>image/x-xpixmap</mime_type>
|
||||
<ensure_nl>true</ensure_nl>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="statement">
|
||||
<rule>
|
||||
<include state="whitespace"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<include state="statements"/>
|
||||
</rule>
|
||||
<rule pattern="[{}]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern=";">
|
||||
<token type="Punctuation"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="function">
|
||||
<rule>
|
||||
<include state="whitespace"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<include state="statements"/>
|
||||
</rule>
|
||||
<rule pattern=";">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="\{">
|
||||
<token type="Punctuation"/>
|
||||
<push/>
|
||||
</rule>
|
||||
<rule pattern="\}">
|
||||
<token type="Punctuation"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"\n]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\\n">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="macro">
|
||||
<rule pattern="(include)(\s*(?:/[*].*?[*]/\s*)?)([^\n]+)">
|
||||
<bygroups>
|
||||
<token type="CommentPreproc"/>
|
||||
<token type="Text"/>
|
||||
<token type="CommentPreprocFile"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="[^/\n]+">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="/[*](.|\n)*?[*]/">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="//.*?\n">
|
||||
<token type="CommentSingle"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="/">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="(?<=\\)\n">
|
||||
<token type="CommentPreproc"/>
|
||||
</rule>
|
||||
<rule pattern="\n">
|
||||
<token type="CommentPreproc"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="if0">
|
||||
<rule pattern="^\s*#if.*?(?<!\\)\n">
|
||||
<token type="CommentPreproc"/>
|
||||
<push/>
|
||||
</rule>
|
||||
<rule pattern="^\s*#el(?:se|if).*\n">
|
||||
<token type="CommentPreproc"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="^\s*#endif.*?(?<!\\)\n">
|
||||
<token type="CommentPreproc"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern=".*?\n">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="whitespace">
|
||||
<rule pattern="^#if\s+0">
|
||||
<token type="CommentPreproc"/>
|
||||
<push state="if0"/>
|
||||
</rule>
|
||||
<rule pattern="^#">
|
||||
<token type="CommentPreproc"/>
|
||||
<push state="macro"/>
|
||||
</rule>
|
||||
<rule pattern="^(\s*(?:/[*].*?[*]/\s*)?)(#if\s+0)">
|
||||
<bygroups>
|
||||
<usingself state="root"/>
|
||||
<token type="CommentPreproc"/>
|
||||
</bygroups>
|
||||
<push state="if0"/>
|
||||
</rule>
|
||||
<rule pattern="^(\s*(?:/[*].*?[*]/\s*)?)(#)">
|
||||
<bygroups>
|
||||
<usingself state="root"/>
|
||||
<token type="CommentPreproc"/>
|
||||
</bygroups>
|
||||
<push state="macro"/>
|
||||
</rule>
|
||||
<rule pattern="\n">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\\\n">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="//(\n|[\w\W]*?[^\\]\n)">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern="/(\\\n)?[*][\w\W]*?[*](\\\n)?/">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="/(\\\n)?[*][\w\W]*">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="statements">
|
||||
<rule pattern="(L?)(")">
|
||||
<bygroups>
|
||||
<token type="LiteralStringAffix"/>
|
||||
<token type="LiteralString"/>
|
||||
</bygroups>
|
||||
<push state="string"/>
|
||||
</rule>
|
||||
<rule pattern="(L?)(')(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])(')">
|
||||
<bygroups>
|
||||
<token type="LiteralStringAffix"/>
|
||||
<token type="LiteralStringChar"/>
|
||||
<token type="LiteralStringChar"/>
|
||||
<token type="LiteralStringChar"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="(\d+\.\d*|\.\d+|\d+[fF])[fF]?">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="0x[0-9a-fA-F]+[LlUu]*">
|
||||
<token type="LiteralNumberHex"/>
|
||||
</rule>
|
||||
<rule pattern="0[0-7]+[LlUu]*">
|
||||
<token type="LiteralNumberOct"/>
|
||||
</rule>
|
||||
<rule pattern="\d+[LlUu]*">
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</rule>
|
||||
<rule pattern="\*/">
|
||||
<token type="Error"/>
|
||||
</rule>
|
||||
<rule pattern="[~!%^&*+=|?:<>/-]">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[()\[\],.]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="(break|case|continue|default|do|else|for|goto|if|return|switch|while|throw|try|catch|extern|MOV|CALL|PUSH|LEAVE|RET|SUB|SHR|ADD|RETF|CMP|JNE|BTS|INT|XOR|JC|JZ|LOOP|POP|TEST|SHL|ADC|SBB|JMP|INC)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(U0|I8|U8|I16|U16|I32|U32|I64|U64|F64|Bool|class|union|DU8|DU16|DU32|DU64|RAX|RCX|RDX|RBX|RSP|RBP|RSI|RDI|EAX|ECX|EDX|EBX|ESP|EBP|ESI|EDI|AX|CX|DX|BX|SP|BP|SI|DI|SS|CS|DS|ES|FS|GS|CH|asm|const|extern|register|restrict|static|volatile|inline|_extern|_import|IMPORT|public)\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="__()\b">
|
||||
<token type="KeywordReserved"/>
|
||||
</rule>
|
||||
<rule pattern="(NULL|TRUE|FALSE|ON|OFF)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="([a-zA-Z_]\w*)(\s*)(:)(?!:)">
|
||||
<bygroups>
|
||||
<token type="NameLabel"/>
|
||||
<token type="Text"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\b[A-Za-z_]\w*(?=\s*\()">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="[a-zA-Z_]\w*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule>
|
||||
<include state="whitespace"/>
|
||||
</rule>
|
||||
<rule pattern="((?:[\w*\s])+?(?:\s|[*]))([a-zA-Z_]\w*)(\s*\([^;]*?\))([^;{]*)(\{)">
|
||||
<bygroups>
|
||||
<usingself state="root"/>
|
||||
<token type="NameFunction"/>
|
||||
<usingself state="root"/>
|
||||
<usingself state="root"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
<push state="function"/>
|
||||
</rule>
|
||||
<rule pattern="((?:[\w*\s])+?(?:\s|[*]))([a-zA-Z_]\w*)(\s*\([^;]*?\))([^;]*)(;)">
|
||||
<bygroups>
|
||||
<usingself state="root"/>
|
||||
<token type="NameFunction"/>
|
||||
<usingself state="root"/>
|
||||
<usingself state="root"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule>
|
||||
<push state="statement"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+4
@@ -7,8 +7,12 @@
|
||||
<filename>*.ini</filename>
|
||||
<filename>*.cfg</filename>
|
||||
<filename>*.inf</filename>
|
||||
<filename>*.service</filename>
|
||||
<filename>*.socket</filename>
|
||||
<filename>.gitconfig</filename>
|
||||
<filename>.editorconfig</filename>
|
||||
<filename>pylintrc</filename>
|
||||
<filename>.pylintrc</filename>
|
||||
<mime_type>text/x-ini</mime_type>
|
||||
<mime_type>text/inf</mime_type>
|
||||
</config>
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>ISCdhcpd</name>
|
||||
<alias>iscdhcpd</alias>
|
||||
<filename>*.conf</filename>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="interpol">
|
||||
<rule pattern="\$[{(]">
|
||||
<token type="LiteralStringInterpol"/>
|
||||
<push/>
|
||||
</rule>
|
||||
<rule pattern="[})]">
|
||||
<token type="LiteralStringInterpol"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="[^${()}]+">
|
||||
<token type="LiteralStringInterpol"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule pattern="#.*?\n">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
<rule pattern="(hardware|packet|leased-address|host-decl-name|lease-time|max-lease-time|client-state|config-option|option|filename|next-server|allow|deny|match|ignore)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(include|group|host|subnet|subnet6|netmask|class|subclass|pool|failover|include|shared-network|range|range6|prefix6)\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="(on|off|true|false|none)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="(if|elsif|else)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(exists|known|static)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="(and|or|not)\b">
|
||||
<token type="OperatorWord"/>
|
||||
</rule>
|
||||
<rule pattern="(==|!=|~=|~~|=)">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[{},;\)]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule pattern="[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}">
|
||||
<token type="LiteralNumberHex"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="doublequotestring"/>
|
||||
</rule>
|
||||
<rule pattern="([\w\-.]+)(\s*)(\()">
|
||||
<bygroups>
|
||||
<token type="NameFunction"/>
|
||||
<token type="Text"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="[\w\-.]+">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="doublequotestring">
|
||||
<rule pattern="\$[{(]">
|
||||
<token type="LiteralStringInterpol"/>
|
||||
<push state="interpol"/>
|
||||
</rule>
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\n">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern=".">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+3
@@ -180,6 +180,9 @@
|
||||
<rule pattern="@(?:[_\p{L}][\p{L}\p{N}]*|`@?[_\p{L}][\p{L}\p{N}]+`)">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="(?:\p{Lu}[_\p{L}]*)(?=\.)">
|
||||
<token type="NameClass"/>
|
||||
</rule>
|
||||
<rule pattern="(?:[_\p{L}][\p{L}\p{N}]*|`@?[_\p{L}][\p{L}\p{N}]+`)">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Natural</name>
|
||||
<alias>natural</alias>
|
||||
<filename>*.NSN</filename>
|
||||
<filename>*.NSP</filename>
|
||||
<filename>*.NSS</filename>
|
||||
<filename>*.NSH</filename>
|
||||
<filename>*.NSG</filename>
|
||||
<filename>*.NSL</filename>
|
||||
<filename>*.NSA</filename>
|
||||
<filename>*.NSM</filename>
|
||||
<filename>*.NSC</filename>
|
||||
<filename>*.NS7</filename>
|
||||
<mime_type>text/x-natural</mime_type>
|
||||
<case_insensitive>true</case_insensitive>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="common">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="^\*.*$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern="/\*.*$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="variable-names">
|
||||
<rule pattern="[#+]?[\w\-\d]+">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="\([a-zA-z]\d*\)">
|
||||
<token type="Other"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule>
|
||||
<include state="common"/>
|
||||
</rule>
|
||||
<rule pattern="(?:END-DEFINE|END-IF|END-FOR|END-SUBROUTINE|END-ERROR|END|IGNORE)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(?:INIT|CONST)\s*<\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(FORM)(\s+)(\w+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="NameFunction"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(DEFINE)(\s+)(SUBROUTINE)(\s+)([#+]?[\w\-\d]+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="NameFunction"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(PERFORM)(\s+)([#+]?[\w\-\d]+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="NameFunction"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(METHOD)(\s+)([\w~]+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="NameFunction"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(\s+)([\w\-]+)([=\-]>)([\w\-~]+)">
|
||||
<bygroups>
|
||||
<token type="Text"/>
|
||||
<token type="NameVariable"/>
|
||||
<token type="Operator"/>
|
||||
<token type="NameFunction"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(?<=(=|-)>)([\w\-~]+)(?=\()">
|
||||
<token type="NameFunction"/>
|
||||
</rule>
|
||||
<rule pattern="(TEXT)(-)(\d{3})">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Punctuation"/>
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(TEXT)(-)(\w{3})">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Punctuation"/>
|
||||
<token type="NameVariable"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(?i)\b(?<!-)(?<!#)(ENTIRE|BY|NAME|ARRAY|SPECIFIED|VIEW|MODULE|FUNCTION|RETURNS|AND|NUMERIC|OPTIONAL|END-PARSE|TRUE|END-RESULT|LEAVING|NOT|CONDITION|NUMBER|NO|EXP|FULL|REPLACE|INSERT|DOEND|LOG|ABS|ANY|REPEAT|SET|DLOGOFF|DOWNLOAD|BREAK|VALUES|DIVIDE|COMPRESS|UPDATE|SORTKEY|OR|END-FIND|END-ENDPAGE|REDUCE|IGNORE|MIN|WASTE|END-DEFINE|SUBSTR|END|FIND|ADD|INVESTIGATE|DNATIVE|CONST|COS|ENDHOC|SGN|COPY|REDEFINE|DEFINE|MULTIPLY|ASSIGN|LE|VALUE|COMPOSE|FALSE|POS|CALL|TAN|ERROR|CLOSE|PARSE|LT|WITH_CTE|END-SORT|EJECT|RESET|SHOW|LOCAL|PERFORM|TERMINATE|VAL|BACKOUT|END-LOOP|REJECT|SUM|CREATE|SORT|RETURN|AT|SIN|SETTIME|INT|NE|GLOBAL|END-SELECT|ELSE|DELETE|TOP|INCLUDE|END-ENDDATA|LOOP|OLD|SUSPEND|SKIP|SQRT|RULEVAR|NMIN|AVER|PROCESS|SELECT|MAP|USING|END-HISTOGRAM|MAX|NEWPAGE|ON|OFF|KEY|NAMED|CONTROL|PF1|PF2|PF3|PF4|PF5|PF6|PF7|PF8|PF9|INITIAL|WRITE|STORE|FETCH|ATN|RET|END-WORK|RESTORE|GET|LIMIT|END-ERROR|SEND|OPEN|ESCAPE|COMPUTE|COUNT|TRANSFER|RELEASE|DO|DYNAMIC|ROLLBACK|END-READ|DISPLAY|UPLOAD|END-DATA|NULL-HANDLE|NCOUNT|RESIZE|END-PROCESS|REQUEST|READ|SEPARATE|EQ|INPUT|DATA|END-START|STACK|REINPUT|INCDIC|INCCONT|END-IF|WHEN|END-BEFORE|WHILE|END-ENDFILE|END-TOPPAGE|INCDIR|PARAMETER|OBTAIN|CALLDBPROC|END-BROWSE|MOVE|SUBTRACT|DLOGON|EXAMINE|SUBSTRING|BEFORE|STOP|RUN|END-BREAK|EXPORT|END-SUBROUTINE|FOR|GE|PRINT|BROWSE|IMPORT|EXPAND|ALL|PASSW|FORMAT|GT|END-NOREC|END-DECIDE|END-FOR|CALLNAT|END-ALL|OPTIONS|RETRY|NONE|INCMAC|END-FILE|DECIDE|INIT|HISTOGRAM|NAVER|START|ACCEPT|COMMIT|TOTAL|IF|FRAC|END-REPEAT|UNTIL|TO|INTO|WITH|DELIMITER|FIRST|OF|INTO|SUBROUTINE|GIVING|POSITION)\b(?!-)">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="[0-9]+">
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</rule>
|
||||
<rule pattern="(?<=(\s|.))(AND|OR|NOT|EQUAL|NE|EQ|GT|GE|LT|LE)\b">
|
||||
<token type="OperatorWord"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<include state="variable-names"/>
|
||||
</rule>
|
||||
<rule pattern="[?*<>=\-+&]">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="(?:(ESCAPE)(\s+)(MODULE|ROUTINE|BOTTOM|TOP))">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="Text"/>
|
||||
<token type="Keyword"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="'(''|[^'])*'">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="`([^`])*`">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="([|}])([^{}|]*?)([|{])">
|
||||
<bygroups>
|
||||
<token type="Punctuation"/>
|
||||
<token type="LiteralStringSingle"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="[/;:()\[\],.]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+4
-4
@@ -44,10 +44,10 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="int-suffix">
|
||||
<rule pattern="\'i(32|64)">
|
||||
<rule pattern="\'(i|u)(32|64)">
|
||||
<token type="LiteralNumberIntegerLong"/>
|
||||
</rule>
|
||||
<rule pattern="\'i(8|16)">
|
||||
<rule pattern="\'(u|(i|u)(8|16))">
|
||||
<token type="LiteralNumberInteger"/>
|
||||
</rule>
|
||||
<rule>
|
||||
@@ -55,7 +55,7 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="float-suffix">
|
||||
<rule pattern="\'f(32|64)">
|
||||
<rule pattern="\'(f|d|f(32|64))">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
</rule>
|
||||
<rule>
|
||||
@@ -176,7 +176,7 @@
|
||||
<rule pattern="\b((?![_\d])\w)(((?!_)\w)|(_(?!_)\w))*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="[0-9][0-9_]*(?=([e.]|\'f(32|64)))">
|
||||
<rule pattern="[0-9][0-9_]*(?=([e.]|\'(f|d|f(32|64))))">
|
||||
<token type="LiteralNumberFloat"/>
|
||||
<push state="float-suffix" state="float-number"/>
|
||||
</rule>
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@
|
||||
<case_insensitive>true</case_insensitive>
|
||||
<dot_all>true</dot_all>
|
||||
<ensure_nl>true</ensure_nl>
|
||||
<priority>3</priority>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="magicfuncs">
|
||||
@@ -208,4 +209,4 @@
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
</lexer>
|
||||
|
||||
+87
-7
@@ -6,6 +6,7 @@
|
||||
<alias>ps1</alias>
|
||||
<alias>psm1</alias>
|
||||
<alias>psd1</alias>
|
||||
<alias>pwsh</alias>
|
||||
<filename>*.ps1</filename>
|
||||
<filename>*.psm1</filename>
|
||||
<filename>*.psd1</filename>
|
||||
@@ -22,6 +23,15 @@
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="(\s*)(#)(requires)(\s+)">
|
||||
<bygroups>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="Comment"/>
|
||||
<token type="Keyword"/>
|
||||
<token type="TextWhitespace"/>
|
||||
</bygroups>
|
||||
<push state="requires"/>
|
||||
</rule>
|
||||
<rule pattern="^(\s*#[#\s]*)(\.(?:component|description|example|externalhelp|forwardhelpcategory|forwardhelptargetname|functionality|inputs|link|notes|outputs|parameter|remotehelprunspace|role|synopsis))([^\n]*$)">
|
||||
<bygroups>
|
||||
<token type="Comment"/>
|
||||
@@ -46,6 +56,9 @@
|
||||
<rule pattern="@'\n.*?\n'@">
|
||||
<token type="LiteralStringHeredoc"/>
|
||||
</rule>
|
||||
<rule pattern="@(?=\(|{)|\$(?=\()">
|
||||
<token type="NameVariableMagic"/>
|
||||
</rule>
|
||||
<rule pattern="`[\'"$@-]">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
@@ -56,13 +69,42 @@
|
||||
<rule pattern="'([^']|'')*'">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(function|filter|workflow)(\s*)(global:|script:|private:|env:)?(\w\S*\b)">
|
||||
<bygroups>
|
||||
<token type="KeywordDeclaration"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="NameVariableMagic"/>
|
||||
<token type="NameBuiltin"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(class|configuration)(\s+)(\w\S*)(\s*)(:*)">
|
||||
<bygroups>
|
||||
<token type="KeywordDeclaration"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="NameBuiltin"/>
|
||||
<token type="NameBuiltin"/>
|
||||
<token type="NameBuiltin"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\$false|\$null|\$true(?=\b)">
|
||||
<token type="NameVariableMagic"/>
|
||||
</rule>
|
||||
<rule pattern="(\$|@@|@)((global|script|private|env):)?\w+">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="(parameter|validatenotnullorempty|validatescript|validaterange|validateset|validaterange|validatepattern|validatelength|validatecount|validatenotnullorempty|validatescript|cmdletbinding|alias)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="[a-z]\w*-[a-z]\w*\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="(while|validateset|validaterange|validatepattern|validatelength|validatecount|until|trap|switch|return|ref|process|param|parameter|in|if|global:|function|foreach|for|finally|filter|end|elseif|else|dynamicparam|do|default|continue|cmdletbinding|break|begin|alias|\?|%|#script|#private|#local|#global|mandatory|parametersetname|position|valuefrompipeline|valuefrompipelinebypropertyname|valuefromremainingarguments|helpmessage|try|catch|throw)\b">
|
||||
<rule pattern="(mandatory|parametersetname|position|helpmessage|valuefrompipeline|valuefrompipelinebypropertyname|valuefromremainingarguments|dontshow)\b">
|
||||
<token type="NameAttribute"/>
|
||||
</rule>
|
||||
<rule pattern="(confirmimpact|defaultparametersetname|helpuri|supportspaging|supportsshouldprocess|positionalbinding)\b">
|
||||
<token type="NameAttribute"/>
|
||||
</rule>
|
||||
<rule pattern="(while|until|trap|switch|return|ref|process|param|parameter|in|if|global:|foreach|for|finally|filter|end|elseif|else|dynamicparam|do|default|continue|break|begin|\?|%|#script|#private|#local|#global|try|catch|throw)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="-(and|as|band|bnot|bor|bxor|casesensitive|ccontains|ceq|cge|cgt|cle|clike|clt|cmatch|cne|cnotcontains|cnotlike|cnotmatch|contains|creplace|eq|exact|f|file|ge|gt|icontains|ieq|ige|igt|ile|ilike|ilt|imatch|ine|inotcontains|inotlike|inotmatch|ireplace|is|isnot|le|like|lt|match|ne|not|notcontains|notlike|notmatch|or|regex|replace|wildcard)\b">
|
||||
@@ -71,19 +113,47 @@
|
||||
<rule pattern="(ac|asnp|cat|cd|cfs|chdir|clc|clear|clhy|cli|clp|cls|clv|cnsn|compare|copy|cp|cpi|cpp|curl|cvpa|dbp|del|diff|dir|dnsn|ebp|echo|epal|epcsv|epsn|erase|etsn|exsn|fc|fhx|fl|foreach|ft|fw|gal|gbp|gc|gci|gcm|gcs|gdr|ghy|gi|gjb|gl|gm|gmo|gp|gps|gpv|group|gsn|gsnp|gsv|gu|gv|gwmi|h|history|icm|iex|ihy|ii|ipal|ipcsv|ipmo|ipsn|irm|ise|iwmi|iwr|kill|lp|ls|man|md|measure|mi|mount|move|mp|mv|nal|ndr|ni|nmo|npssc|nsn|nv|ogv|oh|popd|ps|pushd|pwd|r|rbp|rcjb|rcsn|rd|rdr|ren|ri|rjb|rm|rmdir|rmo|rni|rnp|rp|rsn|rsnp|rujb|rv|rvpa|rwmi|sajb|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spjb|spps|spsv|start|sujb|sv|swmi|tee|trcm|type|wget|where|wjb|write)\s">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="\[[a-z_\[][\w. `,\[\]]*\]">
|
||||
<token type="NameConstant"/>
|
||||
<rule pattern="(\[)([a-z_\[][\w. `,\[\]]*)(\])">
|
||||
<bygroups>
|
||||
<token type="Punctuation"/>
|
||||
<token type="NameConstant"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="-[a-z_]\w*">
|
||||
<rule pattern="(?<!\[)(?<=\S[^\*|\n]\.)\w+(?=\s+|\(|\{|\.)">
|
||||
<token type="NameProperty"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\w)([-+]?(?:[0-9]+)?\.?[0-9]+(?:(?:e|E)[0-9]+)?(?:F|f|D|d|M|m)?)((?i:[kmgtp]b)?)\b">
|
||||
<bygroups>
|
||||
<token type="LiteralNumberFloat"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="-[a-z_]\w*:*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="\w+">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule pattern="[.,;@{}\[\]$()=+*/\\&%!~?^`|<>-]|::">
|
||||
<rule pattern="[.,;@{}\[\]$()=+*/\\&%!~?^\x60|<>-]|::">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="requires">
|
||||
<rule pattern="\s*\n|\s*$">
|
||||
<token type="TextWhitespace"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="-(?i:modules|pssnapin|runasadministrator|ahellid|version|assembly|psedition)">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="-\S*\b">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
<rule pattern="\s+(\S+)">
|
||||
<token type="NameAttribute"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="child">
|
||||
<rule pattern="\)">
|
||||
<token type="Punctuation"/>
|
||||
@@ -101,8 +171,12 @@
|
||||
<token type="CommentMultiline"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\.(component|description|example|externalhelp|forwardhelpcategory|forwardhelptargetname|functionality|inputs|link|notes|outputs|parameter|remotehelprunspace|role|synopsis)">
|
||||
<token type="LiteralStringDoc"/>
|
||||
<rule pattern="(\s*\.)(component|description|example|externalhelp|forwardhelpcategory|forwardhelptargetname|functionality|inputs|link|notes|outputs|parameter|remotehelprunspace|role|synopsis)(\s*$)">
|
||||
<bygroups>
|
||||
<token type="CommentMultiline"/>
|
||||
<token type="LiteralStringDoc"/>
|
||||
<token type="CommentMultiline"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="[#&.]">
|
||||
<token type="CommentMultiline"/>
|
||||
@@ -119,6 +193,9 @@
|
||||
<token type="Punctuation"/>
|
||||
<push state="child"/>
|
||||
</rule>
|
||||
<rule pattern="((\$)((global|script|private|env):)?\w+)|((\$){((global|script|private|env):)?\w+})">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="""">
|
||||
<token type="LiteralStringDouble"/>
|
||||
</rule>
|
||||
@@ -139,6 +216,9 @@
|
||||
<token type="Punctuation"/>
|
||||
<push state="child"/>
|
||||
</rule>
|
||||
<rule pattern="((\$)((global|script|private|env):)?\w+)|((\$){((global|script|private|env):)?\w+})">
|
||||
<token type="NameVariable"/>
|
||||
</rule>
|
||||
<rule pattern="[^@\n]+"]">
|
||||
<token type="LiteralStringHeredoc"/>
|
||||
</rule>
|
||||
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>PSL</name>
|
||||
<alias>psl</alias>
|
||||
<filename>*.psl</filename>
|
||||
<filename>*.BATCH</filename>
|
||||
<filename>*.TRIG</filename>
|
||||
<filename>*.PROC</filename>
|
||||
<mime_type>text/x-psl</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<!-- NameFunction|TypeName -->
|
||||
<state name="root">
|
||||
<rule pattern="[^\S\n]+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\\\n">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\n">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="//.*$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
<rule pattern="/(\\\n)?[*](.|\n)*?[*](\\\n)?/">
|
||||
<token type="CommentMultiline"/>
|
||||
</rule>
|
||||
<rule pattern="\+|-|\*|\/|\b%\b|<|>|=|'|\band\b|\bor\b|_|:|!">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[{}(,)\[\]]">
|
||||
<token type="Punctuation"/>
|
||||
<push state="root"/>
|
||||
</rule>
|
||||
<rule pattern="#">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="directive"/>
|
||||
</rule>
|
||||
<rule pattern="\.?\d+">
|
||||
<token type="LiteralNumber"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="string"/>
|
||||
</rule>
|
||||
<rule pattern="\b(do|set|if|else|for|while|quit|catch|return|ret|while)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\b(true|false)\b">
|
||||
<token type="KeywordConstant"/>
|
||||
</rule>
|
||||
<rule pattern="\btype\b">
|
||||
<token type="KeywordDeclaration"/>
|
||||
<push state="typename"/>
|
||||
</rule>
|
||||
<rule pattern="\b(public|req|private|void)\b">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="\b(Boolean|String|Number|Date)\b">
|
||||
<token type="KeywordType"/>
|
||||
</rule>
|
||||
<rule pattern="(\${0,2}[_a-zA-z]\w*)?(\^[_a-zA-Z]\w*)">
|
||||
<bygroups>
|
||||
<token type="NameFunction"/>
|
||||
<token type="NameClass"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="([_a-zA-z]\w*)(\.[_a-zA-Z]\w*)(\()">
|
||||
<bygroups>
|
||||
<token type="Name"/>
|
||||
<token type="NameFunction"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(\${0,2}[_a-zA-z]\w*)(\.[_a-zA-Z]\w*)">
|
||||
<bygroups>
|
||||
<token type="Name"/>
|
||||
<token type="NameProperty"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\.?(%|\${0,2})[_a-zA-Z]\w*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"\n]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\\n">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="typename">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\b(public|req|private|void)\b">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="([_a-zA-Z]\w*)?(\s+)([_a-zA-Z]\w*)">
|
||||
<bygroups>
|
||||
<token type="NameClass"/>
|
||||
<token type="Text"/>
|
||||
<token type="Name"/>
|
||||
</bygroups>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="directive">
|
||||
<rule pattern="ACCEPT">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="accept-directive"/>
|
||||
</rule>
|
||||
<rule pattern="CLASSDEF">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="classdef-directive"/>
|
||||
</rule>
|
||||
<rule pattern="IF|ELSEIF">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="if-directive"/>
|
||||
</rule>
|
||||
<rule pattern="PACKAGE">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="package-directive"/>
|
||||
</rule>
|
||||
<rule pattern="PROPERTYDEF">
|
||||
<token type="KeywordPseudo"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="INFO|WARN">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="warn-directive"/>
|
||||
</rule>
|
||||
<rule pattern="OPTION">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="option-directive"/>
|
||||
</rule>
|
||||
<rule pattern="BYPASS|ELSE|END|ENDBYPASS|ENDIF|OPTIMIZE">
|
||||
<token type="KeywordPseudo"/>
|
||||
<push state="other-directive"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="accept-directive">
|
||||
<rule pattern=".+$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="other-directive">
|
||||
<rule pattern=".+$">
|
||||
<token type="CommentSingle"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="classdef-directive">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="delimiter|extends">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="public">
|
||||
<token type="KeywordDeclaration"/>
|
||||
</rule>
|
||||
<rule pattern="=">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="[\w\d]+">
|
||||
<token type="NameClass"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="if-directive">
|
||||
<rule pattern=".+$">
|
||||
<include state="root"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="option-directive">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="ON|OFF">
|
||||
<token type="KeywordConstant"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="[\w\d]+">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="package-directive">
|
||||
<rule pattern="\s+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="\w+">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
<rule>
|
||||
<include state="root"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+2
-2
@@ -206,7 +206,7 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="keywords">
|
||||
<rule pattern="(yield from|nonlocal|continue|finally|except|lambda|assert|global|return|raise|yield|while|break|await|async|pass|else|elif|with|try|for|del|as|if)\b">
|
||||
<rule pattern="(yield from|nonlocal|continue|finally|except|lambda|assert|global|return|raise|yield|while|break|await|async|pass|else|elif|with|try|for|del|as|if|match|case)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(False|True|None)\b">
|
||||
@@ -379,7 +379,7 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="name">
|
||||
<rule pattern="@[_\p{L}][_\p{L}\p{N}]*">
|
||||
<rule pattern="@[_\p{L}][_\p{L}\p{N}]*(\s*\.\s*[_\p{L}][_\p{L}\p{N}]*)*">
|
||||
<token type="NameDecorator"/>
|
||||
</rule>
|
||||
<rule pattern="@">
|
||||
|
||||
+65
-19
@@ -23,9 +23,6 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="lifetime">
|
||||
<rule pattern="(static|_)">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="[a-zA-Z_]+\w*">
|
||||
<token type="NameAttribute"/>
|
||||
</rule>
|
||||
@@ -108,12 +105,30 @@
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="formatted_string">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\\['"\\nrt]|\\(?=\n)|\\x[0-7][0-9a-fA-F]|\\0|\\u\{[0-9a-fA-F]{1,6}\}|\{\{|\}\}">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="\{[^}]*\}">
|
||||
<token type="LiteralStringInterpol"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"\{\}]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="\\">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
<rule pattern="\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0|\\u\{[0-9a-fA-F]{1,6}\}">
|
||||
<rule pattern="\\['"\\nrt]|\\(?=\n)|\\x[0-7][0-9a-fA-F]|\\0|\\u\{[0-9a-fA-F]{1,6}\}">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"]+">
|
||||
@@ -171,11 +186,9 @@
|
||||
<token type="CommentMultiline"/>
|
||||
<push state="comment"/>
|
||||
</rule>
|
||||
<rule pattern="r#*"(?:\\.|[^\\;])*"#*">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern=""(?:\\.|[^\\"])*"">
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="string"/>
|
||||
</rule>
|
||||
<rule pattern="\$([a-zA-Z_]\w*|\(,?|\),?|,?)">
|
||||
<token type="CommentPreproc"/>
|
||||
@@ -223,9 +236,6 @@
|
||||
<rule pattern="(DoubleEndedIterator|ExactSizeIterator|IntoIterator|PartialOrd|PartialEq|ToString|Iterator|ToOwned|Default|Result|String|FnOnce|Extend|Option|FnMut|Unpin|Sized|AsRef|AsMut|Clone|None|From|Into|Sync|drop|Send|Drop|Copy|Some|Ord|Err|Box|Vec|Eq|Ok|Fn)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="(is_powerpc64_feature_detected|is_aarch64_feature_detected|is_powerpc_feature_detected|is_mips64_feature_detected|is_mips_feature_detected|is_x86_feature_detected|is_arm_feature_detected|debug_assert_ne|debug_assert_eq|format_args_nl|concat_idents|unimplemented|include_bytes|compile_error|debug_assert|thread_local|trace_macros|macro_rules|format_args|module_path|unreachable|include_str|option_env|global_asm|log_syntax|stringify|assert_ne|assert_eq|llvm_asm|eprintln|include|matches|println|writeln|format|column|assert|concat|eprint|write|panic|print|file|todo|line|env|dbg|vec|cfg|asm)!">
|
||||
<token type="NameFunctionMagic"/>
|
||||
</rule>
|
||||
<rule pattern="::\b">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
@@ -243,8 +253,11 @@
|
||||
<rule pattern="'(\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0|\\u\{[0-9a-fA-F]{1,6}\}|.)'">
|
||||
<token type="LiteralStringChar"/>
|
||||
</rule>
|
||||
<rule pattern="b'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0|\\u\{[0-9a-fA-F]{1,6}\}|.)'">
|
||||
<token type="LiteralStringChar"/>
|
||||
<rule pattern="(b)('(?:\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0|.)')">
|
||||
<bygroups>
|
||||
<token type="LiteralStringAffix"/>
|
||||
<token type="LiteralStringChar"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="0b[01_]+">
|
||||
<token type="LiteralNumberBin"/>
|
||||
@@ -266,15 +279,25 @@
|
||||
<token type="LiteralNumberInteger"/>
|
||||
<push state="number_lit"/>
|
||||
</rule>
|
||||
<rule pattern="b"">
|
||||
<token type="LiteralString"/>
|
||||
<rule pattern="(b)(")">
|
||||
<bygroups>
|
||||
<token type="LiteralStringAffix"/>
|
||||
<token type="LiteralString"/>
|
||||
</bygroups>
|
||||
<push state="bytestring"/>
|
||||
</rule>
|
||||
<rule pattern="(?s)b?r(#*)".*?"\1">
|
||||
<token type="LiteralString"/>
|
||||
<rule pattern="(?s)(b?r)(#*)(".*?"\2)">
|
||||
<bygroups>
|
||||
<token type="LiteralStringAffix"/>
|
||||
<token type="LiteralString"/>
|
||||
<token type="LiteralString"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="'(static|_)">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="Operator"/>
|
||||
<token type="NameAttribute"/>
|
||||
<push state="lifetime"/>
|
||||
</rule>
|
||||
<rule pattern="\.\.=?">
|
||||
@@ -286,6 +309,26 @@
|
||||
<rule pattern="[+\-*/%&|<>^!~@=:?]">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="\b(r#)?_?([A-Z][A-Z0-9_]*){2,}\b">
|
||||
<token type="NameConstant"/>
|
||||
</rule>
|
||||
<rule pattern="((?:e?print(?:ln)?|format(?:_args)?|panic|todo|un(?:reachable|implemented))!)(\s*)(\()(\s*)(")">
|
||||
<bygroups>
|
||||
<token type="NameFunctionMagic"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="Punctuation"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="LiteralString"/>
|
||||
</bygroups>
|
||||
<push state="formatted_string"/>
|
||||
</rule>
|
||||
<rule pattern="([a-zA-Z_]\w*!)(\s*)(\(|\[|\{)">
|
||||
<bygroups>
|
||||
<token type="NameFunctionMagic"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="Punctuation"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="(r#)?[a-zA-Z_]\w*">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
@@ -307,8 +350,11 @@
|
||||
<rule pattern="&">
|
||||
<token type="KeywordPseudo"/>
|
||||
</rule>
|
||||
<rule pattern="'(static|_)">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="Operator"/>
|
||||
<token type="NameAttribute"/>
|
||||
<push state="lifetime"/>
|
||||
</rule>
|
||||
<rule pattern="(DoubleEndedIterator|ExactSizeIterator|IntoIterator|PartialOrd|PartialEq|ToString|Iterator|ToOwned|Default|Result|String|FnOnce|Extend|Option|FnMut|Unpin|Sized|AsRef|AsMut|Clone|None|From|Into|Sync|drop|Send|Drop|Copy|Some|Ord|Err|Box|Vec|Eq|Ok|Fn)\b">
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Sed</name>
|
||||
<alias>sed</alias>
|
||||
<alias>gsed</alias>
|
||||
<alias>ssed</alias>
|
||||
<filename>*.sed</filename>
|
||||
<filename>*.[gs]sed</filename>
|
||||
<mime_type>text/x-sed</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="\s+"><token type="TextWhitespace"/></rule>
|
||||
<rule pattern="#.*$"><token type="CommentSingle"/></rule>
|
||||
<rule pattern="[0-9]+"><token type="LiteralNumberInteger"/></rule>
|
||||
<rule pattern="\$"><token type="Operator"/></rule>
|
||||
<rule pattern="[{};,!]"><token type="Punctuation"/></rule>
|
||||
<rule pattern="[dDFgGhHlnNpPqQxz=]"><token type="Keyword"/></rule>
|
||||
<rule pattern="([berRtTvwW:])([^;\n]*)"><bygroups><token type="Keyword"/><token type="LiteralStringSingle"/></bygroups></rule>
|
||||
<rule pattern="([aci])((?:.*?\\\n)*(?:.*?[^\\]$))"><bygroups><token type="Keyword"/><token type="LiteralStringDouble"/></bygroups></rule>
|
||||
<rule pattern="([qQ])([0-9]*)"><bygroups><token type="Keyword"/><token type="LiteralNumberInteger"/></bygroups></rule>
|
||||
<rule pattern="(/)((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(/)"><bygroups><token type="Punctuation"/><token type="LiteralStringRegex"/><token type="Punctuation"/></bygroups></rule>
|
||||
<rule pattern="(\\(.))((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(\2)"><bygroups><token type="Punctuation"/>None<token type="LiteralStringRegex"/><token type="Punctuation"/></bygroups></rule>
|
||||
<rule pattern="(y)(.)((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(\2)((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(\2)"><bygroups><token type="Keyword"/><token type="Punctuation"/><token type="LiteralStringSingle"/><token type="Punctuation"/><token type="LiteralStringSingle"/><token type="Punctuation"/></bygroups></rule>
|
||||
<rule pattern="(s)(.)((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(\2)((?:(?:\\[^\n]|[^\\])*?\\\n)*?(?:\\.|[^\\])*?)(\2)((?:[gpeIiMm]|[0-9])*)"><bygroups><token type="Keyword"/><token type="Punctuation"/><token type="LiteralStringRegex"/><token type="Punctuation"/><token type="LiteralStringSingle"/><token type="Punctuation"/><token type="Keyword"/></bygroups></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<!--
|
||||
Generated from https://github.com/pygments/pygments/blob/15f222adefd2bf7835bfd74a12d720028ae68d29/pygments/lexers/dalvik.py.
|
||||
-->
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Smali</name>
|
||||
<alias>smali</alias>
|
||||
<filename>*.smali</filename>
|
||||
<mime_type>text/smali</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule><include state="comment"/></rule>
|
||||
<rule><include state="label"/></rule>
|
||||
<rule><include state="field"/></rule>
|
||||
<rule><include state="method"/></rule>
|
||||
<rule><include state="class"/></rule>
|
||||
<rule><include state="directive"/></rule>
|
||||
<rule><include state="access-modifier"/></rule>
|
||||
<rule><include state="instruction"/></rule>
|
||||
<rule><include state="literal"/></rule>
|
||||
<rule><include state="punctuation"/></rule>
|
||||
<rule><include state="type"/></rule>
|
||||
<rule><include state="whitespace"/></rule>
|
||||
</state>
|
||||
<state name="directive">
|
||||
<rule pattern="^([ \t]*)(\.(?:class|super|implements|field|subannotation|annotation|enum|method|registers|locals|array-data|packed-switch|sparse-switch|catchall|catch|line|parameter|local|prologue|epilogue|source))"><bygroups><token type="TextWhitespace"/><token type="Keyword"/></bygroups></rule>
|
||||
<rule pattern="^([ \t]*)(\.end)( )(field|subannotation|annotation|method|array-data|packed-switch|sparse-switch|parameter|local)"><bygroups><token type="TextWhitespace"/><token type="Keyword"/><token type="TextWhitespace"/><token type="Keyword"/></bygroups></rule>
|
||||
<rule pattern="^([ \t]*)(\.restart)( )(local)"><bygroups><token type="TextWhitespace"/><token type="Keyword"/><token type="TextWhitespace"/><token type="Keyword"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="access-modifier">
|
||||
<rule pattern="(public|private|protected|static|final|synchronized|bridge|varargs|native|abstract|strictfp|synthetic|constructor|declared-synchronized|interface|enum|annotation|volatile|transient)"><token type="Keyword"/></rule>
|
||||
</state>
|
||||
<state name="whitespace">
|
||||
<rule pattern="\n"><token type="TextWhitespace"/></rule>
|
||||
<rule pattern="\s+"><token type="TextWhitespace"/></rule>
|
||||
</state>
|
||||
<state name="instruction">
|
||||
<rule pattern="\b[vp]\d+\b"><token type="NameBuiltin"/></rule>
|
||||
<rule pattern="(\b[a-z][A-Za-z0-9/-]+)(\s+)"><bygroups><token type="Text"/><token type="TextWhitespace"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="literal">
|
||||
<rule pattern="".*""><token type="LiteralString"/></rule>
|
||||
<rule pattern="0x[0-9A-Fa-f]+t?"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern="[0-9]*\.[0-9]+([eE][0-9]+)?[fd]?"><token type="LiteralNumberFloat"/></rule>
|
||||
<rule pattern="[0-9]+L?"><token type="LiteralNumberInteger"/></rule>
|
||||
</state>
|
||||
<state name="field">
|
||||
<rule pattern="(\$?\b)([\w$]*)(:)"><bygroups><token type="Punctuation"/><token type="NameVariable"/><token type="Punctuation"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="method">
|
||||
<rule pattern="<(?:cl)?init>"><token type="NameFunction"/></rule>
|
||||
<rule pattern="(\$?\b)([\w$]*)(\()"><bygroups><token type="Punctuation"/><token type="NameFunction"/><token type="Punctuation"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="label">
|
||||
<rule pattern=":\w+"><token type="NameLabel"/></rule>
|
||||
</state>
|
||||
<state name="class">
|
||||
<rule pattern="(L)((?:[\w$]+/)*)([\w$]+)(;)"><bygroups><token type="KeywordType"/><token type="Text"/><token type="NameClass"/><token type="Text"/></bygroups></rule>
|
||||
</state>
|
||||
<state name="punctuation">
|
||||
<rule pattern="->"><token type="Punctuation"/></rule>
|
||||
<rule pattern="[{},():=.-]"><token type="Punctuation"/></rule>
|
||||
</state>
|
||||
<state name="type">
|
||||
<rule pattern="[ZBSCIJFDV\[]+"><token type="KeywordType"/></rule>
|
||||
</state>
|
||||
<state name="comment">
|
||||
<rule pattern="#.*?\n"><token type="Comment"/></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>stas</name>
|
||||
<filename>*.stas</filename>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="string-double-quoted">
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\"]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string-single-quoted">
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\']+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="LiteralString"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="string-char-literal">
|
||||
<rule pattern="\\.">
|
||||
<token type="LiteralStringEscape"/>
|
||||
</rule>
|
||||
<rule pattern="[^\\`]+">
|
||||
<token type="LiteralString"/>
|
||||
</rule>
|
||||
<rule pattern="`">
|
||||
<token type="LiteralStringChar"/>
|
||||
<pop depth="1"/>
|
||||
</rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule pattern="(\n|\s)+">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(fn|argc|argv|swap|dup|over|over2|rot|rot4|drop|w8|w16|w32|w64|r8|r16|r32|r64|syscall0|syscall1|syscall2|syscall3|syscall4|syscall5|syscall6|_breakpoint|assert|const|auto|reserve|pop|include|addr|if|else|elif|while|break|continue|ret)(?!\S)">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(\+|\-|\*|\/|\%|\%\%|\+\+|\-\-|>>|<<)(?!\S)">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(\=|\!\=|>|<|>\=|<\=|>s|<s|>\=s|<\=s)(?!\S)">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)(\&|\||\^|\~|\!|-\>)(?!\S)">
|
||||
<token type="Operator"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)\-?(\d+)(?!\S)">
|
||||
<token type="LiteralNumber"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S);.*(\S|\n)">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
<rule pattern="'">
|
||||
<token type="LiteralString"/>
|
||||
<push state="string-single-quoted"/>
|
||||
</rule>
|
||||
<rule pattern=""">
|
||||
<token type="LiteralString"/>
|
||||
<push state="string-double-quoted"/>
|
||||
</rule>
|
||||
<rule pattern="`">
|
||||
<token type="LiteralStringChar"/>
|
||||
<push state="string-char-literal"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)[{}](?!\S)">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="(?<!\S)[^\s]+(?!\S)">
|
||||
<token type="Name"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Tal</name>
|
||||
<alias>tal</alias>
|
||||
<alias>uxntal</alias>
|
||||
<filename>*.tal</filename>
|
||||
<mime_type>text/x-uxntal</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="comment">
|
||||
<rule pattern="(?<!\S)\((?!\S)"><token type="CommentMultiline"/><push/></rule>
|
||||
<rule pattern="(?<!\S)\)(?!\S)"><token type="CommentMultiline"/><pop depth="1"/></rule>
|
||||
<rule pattern="[^()]+"><token type="CommentMultiline"/></rule>
|
||||
<rule pattern="[()]+"><token type="CommentMultiline"/></rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule pattern="\s+"><token type="TextWhitespace"/></rule>
|
||||
<rule pattern="(?<!\S)\((?!\S)"><token type="CommentMultiline"/><push state="comment"/></rule>
|
||||
<rule pattern="(?<!\S)(BRK|LIT|INC|POP|DUP|NIP|SWP|OVR|ROT|EQU|NEQ|GTH|LTH|JMP|JCN|JSR|STH|LDZ|STZ|LDR|STR|LDA|STA|DEI|DEO|ADD|SUB|MUL|DIV|AND|ORA|EOR|SFT)2?k?r?(?!\S)"><token type="KeywordReserved"/></rule>
|
||||
<rule pattern="[][{}](?!\S)"><token type="Punctuation"/></rule>
|
||||
<rule pattern="#([0-9a-f]{2}){1,2}(?!\S)"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern=""\S+"><token type="LiteralString"/></rule>
|
||||
<rule pattern="([0-9a-f]{2}){1,2}(?!\S)"><token type="Literal"/></rule>
|
||||
<rule pattern="[|$][0-9a-f]{1,4}(?!\S)"><token type="KeywordDeclaration"/></rule>
|
||||
<rule pattern="%\S+"><token type="NameDecorator"/></rule>
|
||||
<rule pattern="@\S+"><token type="NameFunction"/></rule>
|
||||
<rule pattern="&\S+"><token type="NameLabel"/></rule>
|
||||
<rule pattern="/\S+"><token type="NameTag"/></rule>
|
||||
<rule pattern="\.\S+"><token type="NameVariableMagic"/></rule>
|
||||
<rule pattern=",\S+"><token type="NameVariableInstance"/></rule>
|
||||
<rule pattern=";\S+"><token type="NameVariableGlobal"/></rule>
|
||||
<rule pattern="-\S+"><token type="Literal"/></rule>
|
||||
<rule pattern="_\S+"><token type="Literal"/></rule>
|
||||
<rule pattern="=\S+"><token type="Literal"/></rule>
|
||||
<rule pattern="!\S+"><token type="NameFunction"/></rule>
|
||||
<rule pattern="\?\S+"><token type="NameFunction"/></rule>
|
||||
<rule pattern="~\S+"><token type="KeywordNamespace"/></rule>
|
||||
<rule pattern="\S+"><token type="NameFunction"/></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
|
||||
+2
@@ -6,6 +6,8 @@
|
||||
<alias>typescript</alias>
|
||||
<filename>*.ts</filename>
|
||||
<filename>*.tsx</filename>
|
||||
<filename>*.mts</filename>
|
||||
<filename>*.cts</filename>
|
||||
<mime_type>text/x-typescript</mime_type>
|
||||
<dot_all>true</dot_all>
|
||||
<ensure_nl>true</ensure_nl>
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Vala</name>
|
||||
<alias>vala</alias>
|
||||
<alias>vapi</alias>
|
||||
<filename>*.vala</filename>
|
||||
<filename>*.vapi</filename>
|
||||
<mime_type>text/x-vala</mime_type>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="whitespace">
|
||||
<rule pattern="^\s*#if\s+0"><token type="CommentPreproc"/><push state="if0"/></rule>
|
||||
<rule pattern="\n"><token type="TextWhitespace"/></rule>
|
||||
<rule pattern="\s+"><token type="TextWhitespace"/></rule>
|
||||
<rule pattern="\\\n"><token type="Text"/></rule>
|
||||
<rule pattern="//(\n|(.|\n)*?[^\\]\n)"><token type="CommentSingle"/></rule>
|
||||
<rule pattern="/(\\\n)?[*](.|\n)*?[*](\\\n)?/"><token type="CommentMultiline"/></rule>
|
||||
</state>
|
||||
<state name="statements">
|
||||
<rule pattern="[L@]?""><token type="LiteralString"/><push state="string"/></rule>
|
||||
<rule pattern="L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'"><token type="LiteralStringChar"/></rule>
|
||||
<rule pattern="(?s)""".*?""""><token type="LiteralString"/></rule>
|
||||
<rule pattern="(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?"><token type="LiteralNumberFloat"/></rule>
|
||||
<rule pattern="(\d+\.\d*|\.\d+|\d+[fF])[fF]?"><token type="LiteralNumberFloat"/></rule>
|
||||
<rule pattern="0x[0-9a-fA-F]+[Ll]?"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern="0[0-7]+[Ll]?"><token type="LiteralNumberOct"/></rule>
|
||||
<rule pattern="\d+[Ll]?"><token type="LiteralNumberInteger"/></rule>
|
||||
<rule pattern="[~!%^&*+=|?:<>/-]"><token type="Operator"/></rule>
|
||||
<rule pattern="(\[)(Compact|Immutable|(?:Boolean|Simple)Type)(\])"><bygroups><token type="Punctuation"/><token type="NameDecorator"/><token type="Punctuation"/></bygroups></rule>
|
||||
<rule pattern="(\[)(CCode|(?:Integer|Floating)Type)"><bygroups><token type="Punctuation"/><token type="NameDecorator"/></bygroups></rule>
|
||||
<rule pattern="[()\[\],.]"><token type="Punctuation"/></rule>
|
||||
<rule pattern="(as|base|break|case|catch|construct|continue|default|delete|do|else|enum|finally|for|foreach|get|if|in|is|lock|new|out|params|return|set|sizeof|switch|this|throw|try|typeof|while|yield)\b"><token type="Keyword"/></rule>
|
||||
<rule pattern="(abstract|const|delegate|dynamic|ensures|extern|inline|internal|override|owned|private|protected|public|ref|requires|signal|static|throws|unowned|var|virtual|volatile|weak|yields)\b"><token type="KeywordDeclaration"/></rule>
|
||||
<rule pattern="(namespace|using)(\s+)"><bygroups><token type="KeywordNamespace"/><token type="TextWhitespace"/></bygroups><push state="namespace"/></rule>
|
||||
<rule pattern="(class|errordomain|interface|struct)(\s+)"><bygroups><token type="KeywordDeclaration"/><token type="TextWhitespace"/></bygroups><push state="class"/></rule>
|
||||
<rule pattern="(\.)([a-zA-Z_]\w*)"><bygroups><token type="Operator"/><token type="NameAttribute"/></bygroups></rule>
|
||||
<rule pattern="(void|bool|char|double|float|int|int8|int16|int32|int64|long|short|size_t|ssize_t|string|time_t|uchar|uint|uint8|uint16|uint32|uint64|ulong|unichar|ushort)\b"><token type="KeywordType"/></rule>
|
||||
<rule pattern="(true|false|null)\b"><token type="NameBuiltin"/></rule>
|
||||
<rule pattern="[a-zA-Z_]\w*"><token type="Name"/></rule>
|
||||
</state>
|
||||
<state name="root">
|
||||
<rule><include state="whitespace"/></rule>
|
||||
<rule><push state="statement"/></rule>
|
||||
</state>
|
||||
<state name="statement">
|
||||
<rule><include state="whitespace"/></rule>
|
||||
<rule><include state="statements"/></rule>
|
||||
<rule pattern="[{}]"><token type="Punctuation"/></rule>
|
||||
<rule pattern=";"><token type="Punctuation"/><pop depth="1"/></rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern="""><token type="LiteralString"/><pop depth="1"/></rule>
|
||||
<rule pattern="\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})"><token type="LiteralStringEscape"/></rule>
|
||||
<rule pattern="[^\\"\n]+"><token type="LiteralString"/></rule>
|
||||
<rule pattern="\\\n"><token type="LiteralString"/></rule>
|
||||
<rule pattern="\\"><token type="LiteralString"/></rule>
|
||||
</state>
|
||||
<state name="if0">
|
||||
<rule pattern="^\s*#if.*?(?<!\\)\n"><token type="CommentPreproc"/><push/></rule>
|
||||
<rule pattern="^\s*#el(?:se|if).*\n"><token type="CommentPreproc"/><pop depth="1"/></rule>
|
||||
<rule pattern="^\s*#endif.*?(?<!\\)\n"><token type="CommentPreproc"/><pop depth="1"/></rule>
|
||||
<rule pattern=".*?\n"><token type="Comment"/></rule>
|
||||
</state>
|
||||
<state name="class">
|
||||
<rule pattern="[a-zA-Z_]\w*"><token type="NameClass"/><pop depth="1"/></rule>
|
||||
</state>
|
||||
<state name="namespace">
|
||||
<rule pattern="[a-zA-Z_][\w.]*"><token type="NameNamespace"/><pop depth="1"/></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<lexer>
|
||||
<config>
|
||||
<name>VHS</name>
|
||||
<alias>vhs</alias>
|
||||
<alias>tape</alias>
|
||||
<alias>cassette</alias>
|
||||
<filename>*.tape</filename>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern="(Output)(\s+)(.*)(\s+)">
|
||||
<bygroups>
|
||||
<token type="Keyword"/>
|
||||
<token type="TextWhitespace"/>
|
||||
<token type="LiteralString"/>
|
||||
<token type="TextWhitespace"/>
|
||||
</bygroups>
|
||||
</rule>
|
||||
<rule pattern="\b(Set|Type|Left|Right|Up|Down|Backspace|Enter|Tab|Space|Ctrl|Sleep|Hide|Show|Escape)\b">
|
||||
<token type="Keyword"/>
|
||||
</rule>
|
||||
<rule pattern="\b(FontFamily|FontSize|Framerate|Height|Width|Theme|Padding|TypingSpeed|PlaybackSpeed|LineHeight|Framerate|LetterSpacing)\b">
|
||||
<token type="NameBuiltin"/>
|
||||
</rule>
|
||||
<rule pattern="#.*(\S|$)">
|
||||
<token type="Comment"/>
|
||||
</rule>
|
||||
<rule pattern="(?s)".*"">
|
||||
<token type="LiteralStringDouble"/>
|
||||
</rule>
|
||||
<rule pattern="(?s)'.*'">
|
||||
<token type="LiteralStringSingle"/>
|
||||
</rule>
|
||||
<rule pattern="(@|\+)">
|
||||
<token type="Punctuation"/>
|
||||
</rule>
|
||||
<rule pattern="\d+">
|
||||
<token type="LiteralNumber"/>
|
||||
</rule>
|
||||
<rule pattern="\s+">
|
||||
<token type="TextWhitespace"/>
|
||||
</rule>
|
||||
<rule pattern="(ms|s)">
|
||||
<token type="Text"/>
|
||||
</rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
+61
File diff suppressed because one or more lines are too long
+1
-1
@@ -49,7 +49,7 @@
|
||||
</rule>
|
||||
</state>
|
||||
<state name="value">
|
||||
<rule pattern="([>|](?:[+-])?)(\n(^ {1,})(?:.*\n*(?:^\3 *).*)*)">
|
||||
<rule pattern="([>|](?:[+-])?)(\n(^ {1,})(?:(?:.*\n*(?:^\3 *).*)+|.*))">
|
||||
<bygroups>
|
||||
<token type="Punctuation"/>
|
||||
<token type="LiteralStringDoc"/>
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
<lexer>
|
||||
<config>
|
||||
<name>Z80 Assembly</name>
|
||||
<alias>z80</alias>
|
||||
<filename>*.z80</filename>
|
||||
<filename>*.asm</filename>
|
||||
<case_insensitive>true</case_insensitive>
|
||||
</config>
|
||||
<rules>
|
||||
<state name="root">
|
||||
<rule pattern=";.*?$"><token type="CommentSingle"/></rule>
|
||||
<rule pattern="^[.\w]+:"><token type="NameLabel"/></rule>
|
||||
<rule pattern="((0x)|\$)[0-9a-fA-F]+"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern="[0-9][0-9a-fA-F]+h"><token type="LiteralNumberHex"/></rule>
|
||||
<rule pattern="((0b)|%)[01]+"><token type="LiteralNumberBin"/></rule>
|
||||
<rule pattern="-?[0-9]+"><token type="LiteralNumberInteger"/></rule>
|
||||
<rule pattern="""><token type="LiteralString"/><push state="string"/></rule>
|
||||
<rule pattern="'\\?.'"><token type="LiteralStringChar"/></rule>
|
||||
<rule pattern="[,=()\\]"><token type="Punctuation"/></rule>
|
||||
<rule pattern="^\s*#\w+"><token type="CommentPreproc"/></rule>
|
||||
<rule pattern="\.(db|dw|end|org|byte|word|fill|block|addinstr|echo|error|list|nolist|equ|show|option|seek)"><token type="NameBuiltin"/></rule>
|
||||
<rule pattern="(ex|exx|ld|ldd|lddr|ldi|ldir|pop|push|adc|add|cp|cpd|cpdr|cpi|cpir|cpl|daa|dec|inc|neg|sbc|sub|and|bit|ccf|or|res|scf|set|xor|rl|rla|rlc|rlca|rld|rr|rra|rrc|rrca|rrd|sla|sra|srl|call|djnz|jp|jr|ret|rst|nop|reti|retn|di|ei|halt|im|in|ind|indr|ini|inir|out|outd|otdr|outi|otir)"><token type="Keyword"/></rule>
|
||||
<rule pattern="(z|nz|c|nc|po|pe|p|m)"><token type="Keyword"/></rule>
|
||||
<rule pattern="[+-/*~\^&|]"><token type="Operator"/></rule>
|
||||
<rule pattern="\w+"><token type="Text"/></rule>
|
||||
<rule pattern="\s+"><token type="Text"/></rule>
|
||||
</state>
|
||||
<state name="string">
|
||||
<rule pattern="[^"\\]+"><token type="LiteralString"/></rule>
|
||||
<rule pattern="\\."><token type="LiteralStringEscape"/></rule>
|
||||
<rule pattern="""><token type="LiteralString"/><pop depth="1"/></rule>
|
||||
</state>
|
||||
</rules>
|
||||
</lexer>
|
||||
|
||||
+2
-2
@@ -22,8 +22,8 @@ var HTTP = Register(httpBodyContentTypeLexer(MustNewLexer(
|
||||
func httpRules() Rules {
|
||||
return Rules{
|
||||
"root": {
|
||||
{`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)([12]\.[01])(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
|
||||
{`(HTTP)(/)([12]\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
|
||||
{`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)([123](?:\.[01])?)(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
|
||||
{`(HTTP)(/)([123](?:\.[01])?)( +)(\d{3})( *)([^\r\n]*)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
|
||||
},
|
||||
"headers": {
|
||||
{`([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpHeaderBlock), nil},
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import (
|
||||
// Makefile lexer.
|
||||
var Makefile = Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Base Makefile",
|
||||
Name: "Makefile",
|
||||
Aliases: []string{"make", "makefile", "mf", "bsdmake"},
|
||||
Filenames: []string{"*.mak", "*.mk", "Makefile", "makefile", "Makefile.*", "GNUmakefile", "BSDmakefile"},
|
||||
MimeTypes: []string{"text/x-makefile"},
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -655,7 +655,7 @@ func rakuRules() Rules {
|
||||
// Substitution
|
||||
{`(?<=^|\b|\s)(?<!\.)(ss|S|s|TR|tr)\b(\s*)`, ByGroups(Keyword, Text), Push("substitution")},
|
||||
{keywordsPattern, Keyword, nil},
|
||||
{builtinTypesPattern, NameBuiltin, nil},
|
||||
{builtinTypesPattern, KeywordType, nil},
|
||||
{builtinRoutinesPattern, NameBuiltin, nil},
|
||||
// Class name
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user