diff --git a/.drone.yml b/.drone.yml index 57c888a7d..a4079e8e0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -90,7 +90,10 @@ steps: - name: checks-backend image: golang:1.19 commands: + - curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get -qqy install nodejs - make checks-backend + environment: + DEBIAN_FRONTEND: noninteractive depends_on: [deps-backend] volumes: - name: deps @@ -498,6 +501,75 @@ steps: - name: deps path: /go +--- +kind: pipeline +type: docker +name: testing-e2e + +platform: + os: linux + arch: amd64 + +depends_on: + - compliance + +trigger: + event: + - pull_request + +volumes: + - name: deps + temp: {} + +services: + - name: pgsql + pull: default + image: postgres:10 + environment: + POSTGRES_DB: testgitea-e2e + POSTGRES_PASSWORD: postgres + POSTGRES_INITDB_ARGS: --encoding=UTF8 --lc-collate='en_US.UTF-8' --lc-ctype='en_US.UTF-8' + +steps: + - name: deps-frontend + image: node:16 + pull: always + commands: + - make deps-frontend + + - name: build-frontend + image: node:16 + commands: + - make frontend + depends_on: [deps-frontend] + + - name: deps-backend + image: golang:1.18 + pull: always + commands: + - make deps-backend + volumes: + - name: deps + path: /go + + # TODO: We should probably build all dependencies into a test image + - name: test-e2e + image: mcr.microsoft.com/playwright:v1.23.1-focal + commands: + - curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz + - groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea + - apt-get -qq update && apt-get -qqy install build-essential + - export TEST_PGSQL_SCHEMA='' + - ./build/test-env-prepare.sh + - su gitea bash -c "export PATH=$PATH:/usr/local/go/bin && timeout -s ABRT 40m make test-e2e-pgsql" + environment: + GOPROXY: https://goproxy.io + GOSUMDB: sum.golang.org + USE_REPO_TEST_DIR: 1 + TEST_PGSQL_DBNAME: 'testgitea-e2e' + DEBIAN_FRONTEND: noninteractive + depends_on: [build-frontend, deps-backend] + --- kind: pipeline name: update_translations @@ -653,12 +725,13 @@ steps: pull: always commands: # Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved - - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get -qqy install nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not TAGS: bindata sqlite sqlite_unlock_notify + DEBIAN_FRONTEND: noninteractive volumes: - name: deps path: /go @@ -773,12 +846,13 @@ steps: pull: always commands: # Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved - - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get -qqy install nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not TAGS: bindata sqlite sqlite_unlock_notify + DEBIAN_FRONTEND: noninteractive depends_on: [fetch-tags] volumes: - name: deps diff --git a/.gitignore b/.gitignore index eab92b49a..1ce2a8761 100644 --- a/.gitignore +++ b/.gitignore @@ -63,21 +63,14 @@ cpu.out /indexers /log /public/img/avatar -/integrations/gitea-integration-mysql -/integrations/gitea-integration-mysql8 -/integrations/gitea-integration-pgsql -/integrations/gitea-integration-sqlite -/integrations/gitea-integration-mssql -/integrations/indexers-mysql -/integrations/indexers-mysql8 -/integrations/indexers-pgsql -/integrations/indexers-sqlite -/integrations/indexers-mssql -/integrations/sqlite.ini -/integrations/mysql.ini -/integrations/mysql8.ini -/integrations/pgsql.ini -/integrations/mssql.ini +/tests/integration/gitea-integration-* +/tests/integration/indexers-* +/tests/e2e/gitea-e2e-* +/tests/e2e/indexers-* +/tests/e2e/reports +/tests/e2e/test-artifacts +/tests/e2e/test-snapshots +/tests/*.ini /node_modules /yarn.lock /yarn-error.log @@ -102,6 +95,7 @@ cpu.out !/web_src/fomantic/build/themes/default/assets/fonts/outline-icons.woff2 /VERSION /.air +/.go-licenses # Snapcraft snap/.snapcraft/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e8394a9..1f7fbac1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,45 @@ This changelog goes through all the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.io). +## [1.17.1](https://github.com/go-gitea/gitea/releases/tag/1.17.1) - 2022-08-17 + +* SECURITY + * Correctly escape within tribute.js (#20831) (#20832) +* ENHANCEMENTS + * Add support for NuGet API keys (#20721) (#20734) + * Display project in issue list (#20583) + * Add disable download source configuration (#20548) (#20579) + * Add username check to doctor (#20140) (#20671) + * Enable Wire 2 for Internal SSH Server (#20616) (#20617) +* BUGFIXES + * Use the total issue count for UI (#20785) (#20827) + * Add proxy host into allow list (#20798) (#20819) + * Add missing translation for queue flush workers (#20791) (#20792) + * Improve comment header for mobile (#20781) (#20789) + * Fix git.Init for doctor sub-command (#20782) (#20783) + * Check webhooks slice length before calling xorm (#20642) (#20768) + * Remove manual rollback for failed generated repositories (#20639) (#20762) + * Use correct field name in npm template (#20675) (#20760) + * Keep download count on Container tag overwrite (#20728) (#20735) + * Fix v220 migration to be compatible for MSSQL 2008 r2 (#20702) (#20707) + * Use request timeout for git service rpc (#20689) (#20693) + * Send correct NuGet status codes (#20647) (#20677) + * Use correct context to get package content (#20673) (#20676) + * Fix the JS error "EventSource is not defined" caused by some non-standard browsers (#20584) (#20663) + * Add default commit messages to PR for squash merge (#20618) (#20645) + * Fix package upload for files >32mb (#20622) (#20635) + * Fix the new-line copy-paste for rendered code (#20612) + * Clean up and fix clone button script (#20415 & #20600) (#20599) + * Fix default merge style (#20564) (#20565) + * Add repository condition for issue count (#20454) (#20496) + * Make branch icon stand out more (#20726) (#20774) + * Fix loading button with invalid form (#20754) (#20759) + * Fix SecToTime edge-cases (#20610) (#20611) + * Executable check always returns true for windows (#20637) (#20835) + * Check issue labels slice length before calling xorm Insert (#20655) (#20836) + * Fix owners cannot create organization repos bug (#20841) (#20854) + * Prevent 500 is head repo does not have PullRequest unit in IsUserAllowedToUpdate (#20839) (#20848) + ## [1.17.0](https://github.com/go-gitea/gitea/releases/tag/v1.17.0) - 2022-07-30 * BREAKING diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 61ab3de4b..b13af805b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,8 +86,10 @@ Here's how to run the test suite: | | | | :------------------------------------- | :----------------------------------------------- | |``make test[\#TestSpecificName]`` | run unit test | -|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for SQLite | -|[More details about integrations](integrations/README.md) | +|``make test-sqlite[\#TestSpecificName]``| run [integration](tests/integration) test for SQLite | +|[More details about integration tests](tests/integration/README.md) | +|``make test-e2e-sqlite[\#TestSpecificFileName]``| run [end-to-end](tests/e2e) test for SQLite | +|[More details about e2e tests](tests/e2e/README.md) | ## Vendoring @@ -168,7 +170,7 @@ import ( To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts: -- **integration:** Integrations tests +- **integration:** Integration tests - **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging). - **models/fixtures:** Sample model data used in integration tests. - **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step. diff --git a/MAINTAINERS b/MAINTAINERS index 802f04cd9..8c4af7432 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -48,3 +48,4 @@ Gusted (@silentcodeg) Wim (@42wim) xinyu (@penlinux) +Jason Song (@wolfogre) diff --git a/Makefile b/Makefile index 44e245d22..ebd108d99 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,9 @@ GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.3.1 GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.47.0 GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10 MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4 -SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0 +SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.0 XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest +GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.3.0 DOCKER_IMAGE ?= gitea/gitea DOCKER_TAG ?= latest @@ -98,7 +99,7 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 -GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list ./... | grep -v /vendor/)) +GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/)) FOMANTIC_WORK_DIR := web_src/fomantic @@ -110,25 +111,38 @@ WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack pub BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST)) +GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go + SVG_DEST_DIR := public/img/svg AIR_TMP_DIR := .air +GO_LICENSE_TMP_DIR := .go-licenses +GO_LICENSE_FILE := assets/go-licenses.json + TAGS ?= TAGS_SPLIT := $(subst $(COMMA), ,$(TAGS)) TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags TEST_TAGS ?= sqlite sqlite_unlock_notify -TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) +TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) -GO_DIRS := cmd integrations models modules routers build services tools +GO_DIRS := cmd tests models modules routers build services tools GO_SOURCES := $(wildcard *.go) GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go) +GO_SOURCES += $(GENERATED_GO_DEST) +GO_SOURCES_NO_BINDATA := $(GO_SOURCES) ifeq ($(filter $(TAGS_SPLIT),bindata),bindata) GO_SOURCES += $(BINDATA_DEST) + GENERATED_GO_DEST += $(BINDATA_DEST) +endif + +# Force installation of playwright dependencies by setting this flag +ifdef DEPS_PLAYWRIGHT + PLAYWRIGHT_FLAGS += --with-deps endif SWAGGER_SPEC := templates/swagger/v1_json.tmpl @@ -182,6 +196,7 @@ help: @echo " - test test everything" @echo " - test-frontend test frontend files" @echo " - test-backend test backend files" + @echo " - test-e2e[\#TestSpecificName] test end to end using playwright" @echo " - webpack build webpack files" @echo " - svg build svg files" @echo " - fomantic build fomantic files" @@ -193,8 +208,9 @@ help: @echo " - generate-swagger generate the swagger spec from code comments" @echo " - swagger-validate check if the swagger spec is valid" @echo " - golangci-lint run golangci-lint linter" + @echo " - go-licenses regenerate go licenses" @echo " - vet examines Go source code and reports suspicious constructs" - @echo " - tidy run go mod tidy" + @echo " - tidy run go mod tidy and regenerate go licenses" @echo " - test[\#TestSpecificName] run unit test" @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" @echo " - pr# build and start gitea from a PR with integration test data loaded" @@ -236,14 +252,20 @@ clean: $(GO) clean -i ./... rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \ integrations*.test \ - integrations/gitea-integration-pgsql/ integrations/gitea-integration-mysql/ integrations/gitea-integration-mysql8/ integrations/gitea-integration-sqlite/ \ - integrations/gitea-integration-mssql/ integrations/indexers-mysql/ integrations/indexers-mysql8/ integrations/indexers-pgsql integrations/indexers-sqlite \ - integrations/indexers-mssql integrations/mysql.ini integrations/mysql8.ini integrations/pgsql.ini integrations/mssql.ini man/ + e2e*.test \ + tests/integration/gitea-integration-pgsql/ tests/integration/gitea-integration-mysql/ tests/integration/gitea-integration-mysql8/ tests/integration/gitea-integration-sqlite/ \ + tests/integration/gitea-integration-mssql/ tests/integration/indexers-mysql/ tests/integration/indexers-mysql8/ tests/integration/indexers-pgsql tests/integration/indexers-sqlite \ + tests/integration/indexers-mssql tests/mysql.ini tests/mysql8.ini tests/pgsql.ini tests/mssql.ini man/ \ + tests/e2e/gitea-e2e-pgsql/ tests/e2e/gitea-e2e-mysql/ tests/e2e/gitea-e2e-mysql8/ tests/e2e/gitea-e2e-sqlite/ \ + tests/e2e/gitea-e2e-mssql/ tests/e2e/indexers-mysql/ tests/e2e/indexers-mysql8/ tests/e2e/indexers-pgsql/ tests/e2e/indexers-sqlite/ \ + tests/e2e/indexers-mssql/ tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/ .PHONY: fmt fmt: - @echo "Running gitea-fmt (with gofumpt)..." @MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' + $(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl')) + @# strip whitespace after '{{' and before `}}` unless there is only whitespace before it + @$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES) .PHONY: vet vet: @@ -261,7 +283,9 @@ TAGS_PREREQ := $(TAGS_EVIDENCE) endif .PHONY: generate-swagger -generate-swagger: +generate-swagger: $(SWAGGER_SPEC) + +$(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)' @@ -288,13 +312,19 @@ errcheck: .PHONY: fmt-check fmt-check: - # get all go files and run gitea-fmt (with gofmt) on them + @# get all go files and run gitea-fmt (with gofmt) on them @diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \ if [ -n "$$diff" ]; then \ echo "Please run 'make fmt' and commit the result:"; \ echo "$${diff}"; \ exit 1; \ fi + @diff2=$$(git diff templates); \ + if [ -n "$$diff2" ]; then \ + echo "Please run 'make fmt' and commit the result:"; \ + echo "$${diff2}"; \ + exit 1; \ + fi .PHONY: checks checks: checks-frontend checks-backend @@ -303,14 +333,14 @@ checks: checks-frontend checks-backend checks-frontend: lockfile-check svg-check .PHONY: checks-backend -checks-backend: gomod-check swagger-check swagger-validate +checks-backend: tidy-check swagger-check swagger-validate .PHONY: lint lint: lint-frontend lint-backend .PHONY: lint-frontend lint-frontend: node_modules - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js + npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e/*.test.e2e.js tests/e2e/utils_e2e.js npx stylelint --color --max-warnings=0 web_src/less npx spectral lint -q -F hint $(SWAGGER_SPEC) npx markdownlint docs *.md @@ -380,35 +410,45 @@ tidy: vendor: tidy $(GO) mod vendor -.PHONY: gomod-check -gomod-check: tidy - @diff=$$(git diff go.sum); \ +.PHONY: tidy-check +tidy-check: tidy + @diff=$$(git diff go.mod go.sum); \ if [ -n "$$diff" ]; then \ echo "Please run 'make tidy' and commit the result:"; \ echo "$${diff}"; \ exit 1; \ fi +.PHONY: go-licenses +go-licenses: assets/go-licenses.json + +assets/go-licenses.json: go.mod go.sum build/generate-go-licenses.js + -$(GO) run $(GO_LICENSES_PACKAGE) save . --force --save_path="$(GO_LICENSE_TMP_DIR)" 2>/dev/null + node build/generate-go-licenses.js "$(GO_LICENSE_TMP_DIR)" "$(GO_LICENSE_FILE)" + @rm -rf "$(GO_LICENSE_TMP_DIR)" + generate-ini-sqlite: sed -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \ - integrations/sqlite.ini.tmpl > integrations/sqlite.ini + -e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \ + -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \ + tests/sqlite.ini.tmpl > tests/sqlite.ini .PHONY: test-sqlite test-sqlite: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test .PHONY: test-sqlite\#% test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) .PHONY: test-sqlite-migration test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.individual.sqlite.test .PHONY: test-sqlite-migration\#% test-sqlite-migration\#%: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.individual.sqlite.test -test.run $(subst .,/,$*) generate-ini-mysql: @@ -417,20 +457,22 @@ generate-ini-mysql: -e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \ -e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \ -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \ - integrations/mysql.ini.tmpl > integrations/mysql.ini + -e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \ + -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \ + tests/mysql.ini.tmpl > tests/mysql.ini .PHONY: test-mysql test-mysql: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test .PHONY: test-mysql\#% test-mysql\#%: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) .PHONY: test-mysql-migration test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./migrations.mysql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./migrations.individual.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.individual.mysql.test generate-ini-mysql8: sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \ @@ -438,20 +480,22 @@ generate-ini-mysql8: -e 's|{{TEST_MYSQL8_USERNAME}}|${TEST_MYSQL8_USERNAME}|g' \ -e 's|{{TEST_MYSQL8_PASSWORD}}|${TEST_MYSQL8_PASSWORD}|g' \ -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \ - integrations/mysql8.ini.tmpl > integrations/mysql8.ini + -e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \ + -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \ + tests/mysql8.ini.tmpl > tests/mysql8.ini .PHONY: test-mysql8 test-mysql8: integrations.mysql8.test generate-ini-mysql8 - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test .PHONY: test-mysql8\#% test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8 - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*) .PHONY: test-mysql8-migration test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test generate-ini-mysql8 - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./migrations.mysql8.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql8.ini ./migrations.individual.mysql8.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.mysql8.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.individual.mysql8.test generate-ini-pgsql: sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \ @@ -460,20 +504,22 @@ generate-ini-pgsql: -e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \ -e 's|{{TEST_PGSQL_SCHEMA}}|${TEST_PGSQL_SCHEMA}|g' \ -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \ - integrations/pgsql.ini.tmpl > integrations/pgsql.ini + -e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \ + -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \ + tests/pgsql.ini.tmpl > tests/pgsql.ini .PHONY: test-pgsql test-pgsql: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test .PHONY: test-pgsql\#% test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) .PHONY: test-pgsql-migration test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./migrations.pgsql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./migrations.individual.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.individual.pgsql.test generate-ini-mssql: sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \ @@ -481,85 +527,140 @@ generate-ini-mssql: -e 's|{{TEST_MSSQL_USERNAME}}|${TEST_MSSQL_USERNAME}|g' \ -e 's|{{TEST_MSSQL_PASSWORD}}|${TEST_MSSQL_PASSWORD}|g' \ -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \ - integrations/mssql.ini.tmpl > integrations/mssql.ini + -e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \ + -e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \ + tests/mssql.ini.tmpl > tests/mssql.ini .PHONY: test-mssql test-mssql: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test .PHONY: test-mssql\#% test-mssql\#%: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*) .PHONY: test-mssql-migration test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./migrations.mssql.test -test.failfast - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./migrations.individual.mssql.test -test.failfast + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.mssql.test -test.failfast + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.individual.mssql.test -test.failfast + +.PHONY: playwright +playwright: $(PLAYWRIGHT_DIR) + npm install --no-save @playwright/test + npx playwright install $(PLAYWRIGHT_FLAGS) + +.PHONY: test-e2e% +test-e2e%: TEST_TYPE ?= e2e + # Clear display env variable. Otherwise, chromium tests can fail. + DISPLAY= + +.PHONY: test-e2e +test-e2e: test-e2e-sqlite + +.PHONY: test-e2e-sqlite +test-e2e-sqlite: playwright e2e.sqlite.test generate-ini-sqlite + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test + +.PHONY: test-e2e-sqlite\#% +test-e2e-sqlite\#%: playwright e2e.sqlite.test generate-ini-sqlite + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e/$* + +.PHONY: test-e2e-mysql +test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test + +.PHONY: test-e2e-mysql\#% +test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$* + +.PHONY: test-e2e-mysql8 +test-e2e-mysql8: playwright e2e.mysql8.test generate-ini-mysql8 + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test + +.PHONY: test-e2e-mysql8\#% +test-e2e-mysql8\#%: playwright e2e.mysql8.test generate-ini-mysql8 + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test -test.run TestE2e/$* + +.PHONY: test-e2e-pgsql +test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test + +.PHONY: test-e2e-pgsql\#% +test-e2e-pgsql\#%: playwright e2e.pgsql.test generate-ini-pgsql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e/$* + +.PHONY: test-e2e-mssql +test-e2e-mssql: playwright e2e.mssql.test generate-ini-mssql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test + +.PHONY: test-e2e-mssql\#% +test-e2e-mssql\#%: playwright e2e.mssql.test generate-ini-mssql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test -test.run TestE2e/$* .PHONY: bench-sqlite bench-sqlite: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-mysql bench-mysql: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-mssql bench-mssql: integrations.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: bench-pgsql bench-pgsql: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . .PHONY: integration-test-coverage integration-test-coverage: integrations.cover.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out .PHONY: integration-test-coverage-sqlite integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out integrations.mysql.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test integrations.mysql8.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql8.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql8.test integrations.pgsql.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.pgsql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test integrations.mssql.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mssql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mssql.test integrations.sqlite.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags '$(TEST_TAGS)' + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)' integrations.cover.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test integrations.cover.sqlite.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' .PHONY: migrations.mysql.test migrations.mysql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.mysql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test .PHONY: migrations.mysql8.test migrations.mysql8.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.mysql8.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql8.test .PHONY: migrations.pgsql.test migrations.pgsql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.pgsql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test .PHONY: migrations.mssql.test migrations.mssql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.mssql.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mssql.test .PHONY: migrations.sqlite.test migrations.sqlite.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' .PHONY: migrations.individual.mysql.test migrations.individual.mysql.test: $(GO_SOURCES) @@ -581,6 +682,21 @@ migrations.individual.mssql.test: $(GO_SOURCES) migrations.individual.sqlite.test: $(GO_SOURCES) $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.sqlite.test -tags '$(TEST_TAGS)' +e2e.mysql.test: $(GO_SOURCES) + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test + +e2e.mysql8.test: $(GO_SOURCES) + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql8.test + +e2e.pgsql.test: $(GO_SOURCES) + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test + +e2e.mssql.test: $(GO_SOURCES) + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mssql.test + +e2e.sqlite.test: $(GO_SOURCES) + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)' + .PHONY: check check: test @@ -592,16 +708,25 @@ install: $(wildcard *.go) build: frontend backend .PHONY: frontend -frontend: $(WEBPACK_DEST) +frontend: generate-frontend $(WEBPACK_DEST) .PHONY: backend -backend: go-check generate $(EXECUTABLE) +backend: go-check generate-backend $(EXECUTABLE) +# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend .PHONY: generate -generate: $(TAGS_PREREQ) +generate: generate-backend generate-frontend + +.PHONY: generate-backend +generate-backend: $(TAGS_PREREQ) generate-go + +generate-go: $(TAGS_PREREQ) @echo "Running go generate..." @CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES) +.PHONY: generate-frontend +generate-frontend: $(TAGS_PREREQ) go-licenses + $(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@ @@ -686,6 +811,7 @@ deps-backend: $(GO) install $(MISSPELL_PACKAGE) $(GO) install $(SWAGGER_PACKAGE) $(GO) install $(XGO_PACKAGE) + $(GO) install $(GO_LICENSES_PACKAGE) node_modules: package-lock.json npm install --no-save diff --git a/assets/emoji.json b/assets/emoji.json index d28c33cff..bf5f1de60 100644 --- a/assets/emoji.json +++ b/assets/emoji.json @@ -1 +1 @@ -[{"emoji":"๐Ÿ‘","aliases":["+1","thumbsup"]},{"emoji":"๐Ÿ‘Ž","aliases":["-1","thumbsdown"]},{"emoji":"๐Ÿ’ฏ","aliases":["100"]},{"emoji":"๐Ÿ”ข","aliases":["1234"]},{"emoji":"๐Ÿฅ‡","aliases":["1st_place_medal"]},{"emoji":"๐Ÿฅˆ","aliases":["2nd_place_medal"]},{"emoji":"๐Ÿฅ‰","aliases":["3rd_place_medal"]},{"emoji":"๐ŸŽฑ","aliases":["8ball"]},{"emoji":"๐Ÿ…ฐ๏ธ","aliases":["a"]},{"emoji":"๐Ÿ†Ž","aliases":["ab"]},{"emoji":"๐Ÿงฎ","aliases":["abacus"]},{"emoji":"๐Ÿ”ค","aliases":["abc"]},{"emoji":"๐Ÿ”ก","aliases":["abcd"]},{"emoji":"๐Ÿ‰‘","aliases":["accept"]},{"emoji":"๐Ÿฉน","aliases":["adhesive_bandage"]},{"emoji":"๐Ÿง‘","aliases":["adult"]},{"emoji":"๐Ÿšก","aliases":["aerial_tramway"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ซ","aliases":["afghanistan"]},{"emoji":"โœˆ๏ธ","aliases":["airplane"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฝ","aliases":["aland_islands"]},{"emoji":"โฐ","aliases":["alarm_clock"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฑ","aliases":["albania"]},{"emoji":"โš—๏ธ","aliases":["alembic"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฟ","aliases":["algeria"]},{"emoji":"๐Ÿ‘ฝ","aliases":["alien"]},{"emoji":"๐Ÿš‘","aliases":["ambulance"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ธ","aliases":["american_samoa"]},{"emoji":"๐Ÿบ","aliases":["amphora"]},{"emoji":"โš“","aliases":["anchor"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฉ","aliases":["andorra"]},{"emoji":"๐Ÿ‘ผ","aliases":["angel"]},{"emoji":"๐Ÿ’ข","aliases":["anger"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ด","aliases":["angola"]},{"emoji":"๐Ÿ˜ ","aliases":["angry"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฎ","aliases":["anguilla"]},{"emoji":"๐Ÿ˜ง","aliases":["anguished"]},{"emoji":"๐Ÿœ","aliases":["ant"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ถ","aliases":["antarctica"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฌ","aliases":["antigua_barbuda"]},{"emoji":"๐ŸŽ","aliases":["apple"]},{"emoji":"โ™’","aliases":["aquarius"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ท","aliases":["argentina"]},{"emoji":"โ™ˆ","aliases":["aries"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฒ","aliases":["armenia"]},{"emoji":"โ—€๏ธ","aliases":["arrow_backward"]},{"emoji":"โฌ","aliases":["arrow_double_down"]},{"emoji":"โซ","aliases":["arrow_double_up"]},{"emoji":"โฌ‡๏ธ","aliases":["arrow_down"]},{"emoji":"๐Ÿ”ฝ","aliases":["arrow_down_small"]},{"emoji":"โ–ถ๏ธ","aliases":["arrow_forward"]},{"emoji":"โคต๏ธ","aliases":["arrow_heading_down"]},{"emoji":"โคด๏ธ","aliases":["arrow_heading_up"]},{"emoji":"โฌ…๏ธ","aliases":["arrow_left"]},{"emoji":"โ†™๏ธ","aliases":["arrow_lower_left"]},{"emoji":"โ†˜๏ธ","aliases":["arrow_lower_right"]},{"emoji":"โžก๏ธ","aliases":["arrow_right"]},{"emoji":"โ†ช๏ธ","aliases":["arrow_right_hook"]},{"emoji":"โฌ†๏ธ","aliases":["arrow_up"]},{"emoji":"โ†•๏ธ","aliases":["arrow_up_down"]},{"emoji":"๐Ÿ”ผ","aliases":["arrow_up_small"]},{"emoji":"โ†–๏ธ","aliases":["arrow_upper_left"]},{"emoji":"โ†—๏ธ","aliases":["arrow_upper_right"]},{"emoji":"๐Ÿ”ƒ","aliases":["arrows_clockwise"]},{"emoji":"๐Ÿ”„","aliases":["arrows_counterclockwise"]},{"emoji":"๐ŸŽจ","aliases":["art"]},{"emoji":"๐Ÿš›","aliases":["articulated_lorry"]},{"emoji":"๐Ÿ›ฐ๏ธ","aliases":["artificial_satellite"]},{"emoji":"๐Ÿง‘โ€๐ŸŽจ","aliases":["artist"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ผ","aliases":["aruba"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡จ","aliases":["ascension_island"]},{"emoji":"*๏ธโƒฃ","aliases":["asterisk"]},{"emoji":"๐Ÿ˜ฒ","aliases":["astonished"]},{"emoji":"๐Ÿง‘โ€๐Ÿš€","aliases":["astronaut"]},{"emoji":"๐Ÿ‘Ÿ","aliases":["athletic_shoe"]},{"emoji":"๐Ÿง","aliases":["atm"]},{"emoji":"โš›๏ธ","aliases":["atom_symbol"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡บ","aliases":["australia"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡น","aliases":["austria"]},{"emoji":"๐Ÿ›บ","aliases":["auto_rickshaw"]},{"emoji":"๐Ÿฅ‘","aliases":["avocado"]},{"emoji":"๐Ÿช“","aliases":["axe"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฟ","aliases":["azerbaijan"]},{"emoji":"๐Ÿ…ฑ๏ธ","aliases":["b"]},{"emoji":"๐Ÿ‘ถ","aliases":["baby"]},{"emoji":"๐Ÿผ","aliases":["baby_bottle"]},{"emoji":"๐Ÿค","aliases":["baby_chick"]},{"emoji":"๐Ÿšผ","aliases":["baby_symbol"]},{"emoji":"๐Ÿ”™","aliases":["back"]},{"emoji":"๐Ÿฅ“","aliases":["bacon"]},{"emoji":"๐Ÿฆก","aliases":["badger"]},{"emoji":"๐Ÿธ","aliases":["badminton"]},{"emoji":"๐Ÿฅฏ","aliases":["bagel"]},{"emoji":"๐Ÿ›„","aliases":["baggage_claim"]},{"emoji":"๐Ÿฅ–","aliases":["baguette_bread"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ธ","aliases":["bahamas"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ญ","aliases":["bahrain"]},{"emoji":"โš–๏ธ","aliases":["balance_scale"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฒ","aliases":["bald_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฒ","aliases":["bald_woman"]},{"emoji":"๐Ÿฉฐ","aliases":["ballet_shoes"]},{"emoji":"๐ŸŽˆ","aliases":["balloon"]},{"emoji":"๐Ÿ—ณ๏ธ","aliases":["ballot_box"]},{"emoji":"โ˜‘๏ธ","aliases":["ballot_box_with_check"]},{"emoji":"๐ŸŽ","aliases":["bamboo"]},{"emoji":"๐ŸŒ","aliases":["banana"]},{"emoji":"โ€ผ๏ธ","aliases":["bangbang"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฉ","aliases":["bangladesh"]},{"emoji":"๐Ÿช•","aliases":["banjo"]},{"emoji":"๐Ÿฆ","aliases":["bank"]},{"emoji":"๐Ÿ“Š","aliases":["bar_chart"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ง","aliases":["barbados"]},{"emoji":"๐Ÿ’ˆ","aliases":["barber"]},{"emoji":"โšพ","aliases":["baseball"]},{"emoji":"๐Ÿงบ","aliases":["basket"]},{"emoji":"๐Ÿ€","aliases":["basketball"]},{"emoji":"๐Ÿฆ‡","aliases":["bat"]},{"emoji":"๐Ÿ›€","aliases":["bath"]},{"emoji":"๐Ÿ›","aliases":["bathtub"]},{"emoji":"๐Ÿ”‹","aliases":["battery"]},{"emoji":"๐Ÿ–๏ธ","aliases":["beach_umbrella"]},{"emoji":"๐Ÿป","aliases":["bear"]},{"emoji":"๐Ÿง”","aliases":["bearded_person"]},{"emoji":"๐Ÿ›๏ธ","aliases":["bed"]},{"emoji":"๐Ÿ","aliases":["bee","honeybee"]},{"emoji":"๐Ÿบ","aliases":["beer"]},{"emoji":"๐Ÿป","aliases":["beers"]},{"emoji":"๐Ÿ”ฐ","aliases":["beginner"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡พ","aliases":["belarus"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ช","aliases":["belgium"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฟ","aliases":["belize"]},{"emoji":"๐Ÿ””","aliases":["bell"]},{"emoji":"๐Ÿ›Ž๏ธ","aliases":["bellhop_bell"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฏ","aliases":["benin"]},{"emoji":"๐Ÿฑ","aliases":["bento"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฒ","aliases":["bermuda"]},{"emoji":"๐Ÿงƒ","aliases":["beverage_box"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡น","aliases":["bhutan"]},{"emoji":"๐Ÿšด","aliases":["bicyclist"]},{"emoji":"๐Ÿšฒ","aliases":["bike"]},{"emoji":"๐Ÿšดโ€โ™‚๏ธ","aliases":["biking_man"]},{"emoji":"๐Ÿšดโ€โ™€๏ธ","aliases":["biking_woman"]},{"emoji":"๐Ÿ‘™","aliases":["bikini"]},{"emoji":"๐Ÿงข","aliases":["billed_cap"]},{"emoji":"โ˜ฃ๏ธ","aliases":["biohazard"]},{"emoji":"๐Ÿฆ","aliases":["bird"]},{"emoji":"๐ŸŽ‚","aliases":["birthday"]},{"emoji":"โšซ","aliases":["black_circle"]},{"emoji":"๐Ÿด","aliases":["black_flag"]},{"emoji":"๐Ÿ–ค","aliases":["black_heart"]},{"emoji":"๐Ÿƒ","aliases":["black_joker"]},{"emoji":"โฌ›","aliases":["black_large_square"]},{"emoji":"โ—พ","aliases":["black_medium_small_square"]},{"emoji":"โ—ผ๏ธ","aliases":["black_medium_square"]},{"emoji":"โœ’๏ธ","aliases":["black_nib"]},{"emoji":"โ–ช๏ธ","aliases":["black_small_square"]},{"emoji":"๐Ÿ”ฒ","aliases":["black_square_button"]},{"emoji":"๐Ÿ‘ฑโ€โ™‚๏ธ","aliases":["blond_haired_man"]},{"emoji":"๐Ÿ‘ฑ","aliases":["blond_haired_person"]},{"emoji":"๐Ÿ‘ฑโ€โ™€๏ธ","aliases":["blond_haired_woman","blonde_woman"]},{"emoji":"๐ŸŒผ","aliases":["blossom"]},{"emoji":"๐Ÿก","aliases":["blowfish"]},{"emoji":"๐Ÿ“˜","aliases":["blue_book"]},{"emoji":"๐Ÿš™","aliases":["blue_car"]},{"emoji":"๐Ÿ’™","aliases":["blue_heart"]},{"emoji":"๐ŸŸฆ","aliases":["blue_square"]},{"emoji":"๐Ÿ˜Š","aliases":["blush"]},{"emoji":"๐Ÿ—","aliases":["boar"]},{"emoji":"โ›ต","aliases":["boat","sailboat"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ด","aliases":["bolivia"]},{"emoji":"๐Ÿ’ฃ","aliases":["bomb"]},{"emoji":"๐Ÿฆด","aliases":["bone"]},{"emoji":"๐Ÿ“–","aliases":["book","open_book"]},{"emoji":"๐Ÿ”–","aliases":["bookmark"]},{"emoji":"๐Ÿ“‘","aliases":["bookmark_tabs"]},{"emoji":"๐Ÿ“š","aliases":["books"]},{"emoji":"๐Ÿ’ฅ","aliases":["boom","collision"]},{"emoji":"๐Ÿ‘ข","aliases":["boot"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฆ","aliases":["bosnia_herzegovina"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ผ","aliases":["botswana"]},{"emoji":"โ›น๏ธโ€โ™‚๏ธ","aliases":["bouncing_ball_man","basketball_man"]},{"emoji":"โ›น๏ธ","aliases":["bouncing_ball_person"]},{"emoji":"โ›น๏ธโ€โ™€๏ธ","aliases":["bouncing_ball_woman","basketball_woman"]},{"emoji":"๐Ÿ’","aliases":["bouquet"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ป","aliases":["bouvet_island"]},{"emoji":"๐Ÿ™‡","aliases":["bow"]},{"emoji":"๐Ÿน","aliases":["bow_and_arrow"]},{"emoji":"๐Ÿ™‡โ€โ™‚๏ธ","aliases":["bowing_man"]},{"emoji":"๐Ÿ™‡โ€โ™€๏ธ","aliases":["bowing_woman"]},{"emoji":"๐Ÿฅฃ","aliases":["bowl_with_spoon"]},{"emoji":"๐ŸŽณ","aliases":["bowling"]},{"emoji":"๐ŸฅŠ","aliases":["boxing_glove"]},{"emoji":"๐Ÿ‘ฆ","aliases":["boy"]},{"emoji":"๐Ÿง ","aliases":["brain"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ท","aliases":["brazil"]},{"emoji":"๐Ÿž","aliases":["bread"]},{"emoji":"๐Ÿคฑ","aliases":["breast_feeding"]},{"emoji":"๐Ÿงฑ","aliases":["bricks"]},{"emoji":"๐ŸŒ‰","aliases":["bridge_at_night"]},{"emoji":"๐Ÿ’ผ","aliases":["briefcase"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ด","aliases":["british_indian_ocean_territory"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฌ","aliases":["british_virgin_islands"]},{"emoji":"๐Ÿฅฆ","aliases":["broccoli"]},{"emoji":"๐Ÿ’”","aliases":["broken_heart"]},{"emoji":"๐Ÿงน","aliases":["broom"]},{"emoji":"๐ŸŸค","aliases":["brown_circle"]},{"emoji":"๐ŸคŽ","aliases":["brown_heart"]},{"emoji":"๐ŸŸซ","aliases":["brown_square"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ณ","aliases":["brunei"]},{"emoji":"๐Ÿ›","aliases":["bug"]},{"emoji":"๐Ÿ—๏ธ","aliases":["building_construction"]},{"emoji":"๐Ÿ’ก","aliases":["bulb"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฌ","aliases":["bulgaria"]},{"emoji":"๐Ÿš…","aliases":["bullettrain_front"]},{"emoji":"๐Ÿš„","aliases":["bullettrain_side"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ซ","aliases":["burkina_faso"]},{"emoji":"๐ŸŒฏ","aliases":["burrito"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฎ","aliases":["burundi"]},{"emoji":"๐ŸšŒ","aliases":["bus"]},{"emoji":"๐Ÿ•ด๏ธ","aliases":["business_suit_levitating"]},{"emoji":"๐Ÿš","aliases":["busstop"]},{"emoji":"๐Ÿ‘ค","aliases":["bust_in_silhouette"]},{"emoji":"๐Ÿ‘ฅ","aliases":["busts_in_silhouette"]},{"emoji":"๐Ÿงˆ","aliases":["butter"]},{"emoji":"๐Ÿฆ‹","aliases":["butterfly"]},{"emoji":"๐ŸŒต","aliases":["cactus"]},{"emoji":"๐Ÿฐ","aliases":["cake"]},{"emoji":"๐Ÿ“†","aliases":["calendar"]},{"emoji":"๐Ÿค™","aliases":["call_me_hand"]},{"emoji":"๐Ÿ“ฒ","aliases":["calling"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ญ","aliases":["cambodia"]},{"emoji":"๐Ÿซ","aliases":["camel"]},{"emoji":"๐Ÿ“ท","aliases":["camera"]},{"emoji":"๐Ÿ“ธ","aliases":["camera_flash"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฒ","aliases":["cameroon"]},{"emoji":"๐Ÿ•๏ธ","aliases":["camping"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฆ","aliases":["canada"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡จ","aliases":["canary_islands"]},{"emoji":"โ™‹","aliases":["cancer"]},{"emoji":"๐Ÿ•ฏ๏ธ","aliases":["candle"]},{"emoji":"๐Ÿฌ","aliases":["candy"]},{"emoji":"๐Ÿฅซ","aliases":["canned_food"]},{"emoji":"๐Ÿ›ถ","aliases":["canoe"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ป","aliases":["cape_verde"]},{"emoji":"๐Ÿ” ","aliases":["capital_abcd"]},{"emoji":"โ™‘","aliases":["capricorn"]},{"emoji":"๐Ÿš—","aliases":["car","red_car"]},{"emoji":"๐Ÿ—ƒ๏ธ","aliases":["card_file_box"]},{"emoji":"๐Ÿ“‡","aliases":["card_index"]},{"emoji":"๐Ÿ—‚๏ธ","aliases":["card_index_dividers"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ถ","aliases":["caribbean_netherlands"]},{"emoji":"๐ŸŽ ","aliases":["carousel_horse"]},{"emoji":"๐Ÿฅ•","aliases":["carrot"]},{"emoji":"๐Ÿคธ","aliases":["cartwheeling"]},{"emoji":"๐Ÿฑ","aliases":["cat"]},{"emoji":"๐Ÿˆ","aliases":["cat2"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡พ","aliases":["cayman_islands"]},{"emoji":"๐Ÿ’ฟ","aliases":["cd"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ซ","aliases":["central_african_republic"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ฆ","aliases":["ceuta_melilla"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฉ","aliases":["chad"]},{"emoji":"โ›“๏ธ","aliases":["chains"]},{"emoji":"๐Ÿช‘","aliases":["chair"]},{"emoji":"๐Ÿพ","aliases":["champagne"]},{"emoji":"๐Ÿ’น","aliases":["chart"]},{"emoji":"๐Ÿ“‰","aliases":["chart_with_downwards_trend"]},{"emoji":"๐Ÿ“ˆ","aliases":["chart_with_upwards_trend"]},{"emoji":"๐Ÿ","aliases":["checkered_flag"]},{"emoji":"๐Ÿง€","aliases":["cheese"]},{"emoji":"๐Ÿ’","aliases":["cherries"]},{"emoji":"๐ŸŒธ","aliases":["cherry_blossom"]},{"emoji":"โ™Ÿ๏ธ","aliases":["chess_pawn"]},{"emoji":"๐ŸŒฐ","aliases":["chestnut"]},{"emoji":"๐Ÿ”","aliases":["chicken"]},{"emoji":"๐Ÿง’","aliases":["child"]},{"emoji":"๐Ÿšธ","aliases":["children_crossing"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฑ","aliases":["chile"]},{"emoji":"๐Ÿฟ๏ธ","aliases":["chipmunk"]},{"emoji":"๐Ÿซ","aliases":["chocolate_bar"]},{"emoji":"๐Ÿฅข","aliases":["chopsticks"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฝ","aliases":["christmas_island"]},{"emoji":"๐ŸŽ„","aliases":["christmas_tree"]},{"emoji":"โ›ช","aliases":["church"]},{"emoji":"๐ŸŽฆ","aliases":["cinema"]},{"emoji":"๐ŸŽช","aliases":["circus_tent"]},{"emoji":"๐ŸŒ‡","aliases":["city_sunrise"]},{"emoji":"๐ŸŒ†","aliases":["city_sunset"]},{"emoji":"๐Ÿ™๏ธ","aliases":["cityscape"]},{"emoji":"๐Ÿ†‘","aliases":["cl"]},{"emoji":"๐Ÿ—œ๏ธ","aliases":["clamp"]},{"emoji":"๐Ÿ‘","aliases":["clap"]},{"emoji":"๐ŸŽฌ","aliases":["clapper"]},{"emoji":"๐Ÿ›๏ธ","aliases":["classical_building"]},{"emoji":"๐Ÿง—","aliases":["climbing"]},{"emoji":"๐Ÿง—โ€โ™‚๏ธ","aliases":["climbing_man"]},{"emoji":"๐Ÿง—โ€โ™€๏ธ","aliases":["climbing_woman"]},{"emoji":"๐Ÿฅ‚","aliases":["clinking_glasses"]},{"emoji":"๐Ÿ“‹","aliases":["clipboard"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ต","aliases":["clipperton_island"]},{"emoji":"๐Ÿ•","aliases":["clock1"]},{"emoji":"๐Ÿ•™","aliases":["clock10"]},{"emoji":"๐Ÿ•ฅ","aliases":["clock1030"]},{"emoji":"๐Ÿ•š","aliases":["clock11"]},{"emoji":"๐Ÿ•ฆ","aliases":["clock1130"]},{"emoji":"๐Ÿ•›","aliases":["clock12"]},{"emoji":"๐Ÿ•ง","aliases":["clock1230"]},{"emoji":"๐Ÿ•œ","aliases":["clock130"]},{"emoji":"๐Ÿ•‘","aliases":["clock2"]},{"emoji":"๐Ÿ•","aliases":["clock230"]},{"emoji":"๐Ÿ•’","aliases":["clock3"]},{"emoji":"๐Ÿ•ž","aliases":["clock330"]},{"emoji":"๐Ÿ•“","aliases":["clock4"]},{"emoji":"๐Ÿ•Ÿ","aliases":["clock430"]},{"emoji":"๐Ÿ•”","aliases":["clock5"]},{"emoji":"๐Ÿ• ","aliases":["clock530"]},{"emoji":"๐Ÿ••","aliases":["clock6"]},{"emoji":"๐Ÿ•ก","aliases":["clock630"]},{"emoji":"๐Ÿ•–","aliases":["clock7"]},{"emoji":"๐Ÿ•ข","aliases":["clock730"]},{"emoji":"๐Ÿ•—","aliases":["clock8"]},{"emoji":"๐Ÿ•ฃ","aliases":["clock830"]},{"emoji":"๐Ÿ•˜","aliases":["clock9"]},{"emoji":"๐Ÿ•ค","aliases":["clock930"]},{"emoji":"๐Ÿ“•","aliases":["closed_book"]},{"emoji":"๐Ÿ”","aliases":["closed_lock_with_key"]},{"emoji":"๐ŸŒ‚","aliases":["closed_umbrella"]},{"emoji":"โ˜๏ธ","aliases":["cloud"]},{"emoji":"๐ŸŒฉ๏ธ","aliases":["cloud_with_lightning"]},{"emoji":"โ›ˆ๏ธ","aliases":["cloud_with_lightning_and_rain"]},{"emoji":"๐ŸŒง๏ธ","aliases":["cloud_with_rain"]},{"emoji":"๐ŸŒจ๏ธ","aliases":["cloud_with_snow"]},{"emoji":"๐Ÿคก","aliases":["clown_face"]},{"emoji":"โ™ฃ๏ธ","aliases":["clubs"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ณ","aliases":["cn"]},{"emoji":"๐Ÿงฅ","aliases":["coat"]},{"emoji":"๐Ÿธ","aliases":["cocktail"]},{"emoji":"๐Ÿฅฅ","aliases":["coconut"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡จ","aliases":["cocos_islands"]},{"emoji":"โ˜•","aliases":["coffee"]},{"emoji":"โšฐ๏ธ","aliases":["coffin"]},{"emoji":"๐Ÿฅถ","aliases":["cold_face"]},{"emoji":"๐Ÿ˜ฐ","aliases":["cold_sweat"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ด","aliases":["colombia"]},{"emoji":"โ˜„๏ธ","aliases":["comet"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฒ","aliases":["comoros"]},{"emoji":"๐Ÿงญ","aliases":["compass"]},{"emoji":"๐Ÿ’ป","aliases":["computer"]},{"emoji":"๐Ÿ–ฑ๏ธ","aliases":["computer_mouse"]},{"emoji":"๐ŸŽŠ","aliases":["confetti_ball"]},{"emoji":"๐Ÿ˜–","aliases":["confounded"]},{"emoji":"๐Ÿ˜•","aliases":["confused"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฌ","aliases":["congo_brazzaville"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฉ","aliases":["congo_kinshasa"]},{"emoji":"ใŠ—๏ธ","aliases":["congratulations"]},{"emoji":"๐Ÿšง","aliases":["construction"]},{"emoji":"๐Ÿ‘ท","aliases":["construction_worker"]},{"emoji":"๐Ÿ‘ทโ€โ™‚๏ธ","aliases":["construction_worker_man"]},{"emoji":"๐Ÿ‘ทโ€โ™€๏ธ","aliases":["construction_worker_woman"]},{"emoji":"๐ŸŽ›๏ธ","aliases":["control_knobs"]},{"emoji":"๐Ÿช","aliases":["convenience_store"]},{"emoji":"๐Ÿง‘โ€๐Ÿณ","aliases":["cook"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฐ","aliases":["cook_islands"]},{"emoji":"๐Ÿช","aliases":["cookie"]},{"emoji":"๐Ÿ†’","aliases":["cool"]},{"emoji":"ยฉ๏ธ","aliases":["copyright"]},{"emoji":"๐ŸŒฝ","aliases":["corn"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ท","aliases":["costa_rica"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฎ","aliases":["cote_divoire"]},{"emoji":"๐Ÿ›‹๏ธ","aliases":["couch_and_lamp"]},{"emoji":"๐Ÿ‘ซ","aliases":["couple"]},{"emoji":"๐Ÿ’‘","aliases":["couple_with_heart"]},{"emoji":"๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ","aliases":["couple_with_heart_man_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ","aliases":["couple_with_heart_woman_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ","aliases":["couple_with_heart_woman_woman"]},{"emoji":"๐Ÿ’","aliases":["couplekiss"]},{"emoji":"๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ","aliases":["couplekiss_man_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ","aliases":["couplekiss_man_woman"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ","aliases":["couplekiss_woman_woman"]},{"emoji":"๐Ÿฎ","aliases":["cow"]},{"emoji":"๐Ÿ„","aliases":["cow2"]},{"emoji":"๐Ÿค ","aliases":["cowboy_hat_face"]},{"emoji":"๐Ÿฆ€","aliases":["crab"]},{"emoji":"๐Ÿ–๏ธ","aliases":["crayon"]},{"emoji":"๐Ÿ’ณ","aliases":["credit_card"]},{"emoji":"๐ŸŒ™","aliases":["crescent_moon"]},{"emoji":"๐Ÿฆ—","aliases":["cricket"]},{"emoji":"๐Ÿ","aliases":["cricket_game"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ท","aliases":["croatia"]},{"emoji":"๐ŸŠ","aliases":["crocodile"]},{"emoji":"๐Ÿฅ","aliases":["croissant"]},{"emoji":"๐Ÿคž","aliases":["crossed_fingers"]},{"emoji":"๐ŸŽŒ","aliases":["crossed_flags"]},{"emoji":"โš”๏ธ","aliases":["crossed_swords"]},{"emoji":"๐Ÿ‘‘","aliases":["crown"]},{"emoji":"๐Ÿ˜ข","aliases":["cry"]},{"emoji":"๐Ÿ˜ฟ","aliases":["crying_cat_face"]},{"emoji":"๐Ÿ”ฎ","aliases":["crystal_ball"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡บ","aliases":["cuba"]},{"emoji":"๐Ÿฅ’","aliases":["cucumber"]},{"emoji":"๐Ÿฅค","aliases":["cup_with_straw"]},{"emoji":"๐Ÿง","aliases":["cupcake"]},{"emoji":"๐Ÿ’˜","aliases":["cupid"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ผ","aliases":["curacao"]},{"emoji":"๐ŸฅŒ","aliases":["curling_stone"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฑ","aliases":["curly_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฑ","aliases":["curly_haired_woman"]},{"emoji":"โžฐ","aliases":["curly_loop"]},{"emoji":"๐Ÿ’ฑ","aliases":["currency_exchange"]},{"emoji":"๐Ÿ›","aliases":["curry"]},{"emoji":"๐Ÿคฌ","aliases":["cursing_face"]},{"emoji":"๐Ÿฎ","aliases":["custard"]},{"emoji":"๐Ÿ›ƒ","aliases":["customs"]},{"emoji":"๐Ÿฅฉ","aliases":["cut_of_meat"]},{"emoji":"๐ŸŒ€","aliases":["cyclone"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡พ","aliases":["cyprus"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฟ","aliases":["czech_republic"]},{"emoji":"๐Ÿ—ก๏ธ","aliases":["dagger"]},{"emoji":"๐Ÿ‘ฏ","aliases":["dancers"]},{"emoji":"๐Ÿ‘ฏโ€โ™‚๏ธ","aliases":["dancing_men"]},{"emoji":"๐Ÿ‘ฏโ€โ™€๏ธ","aliases":["dancing_women"]},{"emoji":"๐Ÿก","aliases":["dango"]},{"emoji":"๐Ÿ•ถ๏ธ","aliases":["dark_sunglasses"]},{"emoji":"๐ŸŽฏ","aliases":["dart"]},{"emoji":"๐Ÿ’จ","aliases":["dash"]},{"emoji":"๐Ÿ“…","aliases":["date"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ช","aliases":["de"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["deaf_man"]},{"emoji":"๐Ÿง","aliases":["deaf_person"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["deaf_woman"]},{"emoji":"๐ŸŒณ","aliases":["deciduous_tree"]},{"emoji":"๐ŸฆŒ","aliases":["deer"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฐ","aliases":["denmark"]},{"emoji":"๐Ÿฌ","aliases":["department_store"]},{"emoji":"๐Ÿš๏ธ","aliases":["derelict_house"]},{"emoji":"๐Ÿœ๏ธ","aliases":["desert"]},{"emoji":"๐Ÿ๏ธ","aliases":["desert_island"]},{"emoji":"๐Ÿ–ฅ๏ธ","aliases":["desktop_computer"]},{"emoji":"๐Ÿ•ต๏ธ","aliases":["detective"]},{"emoji":"๐Ÿ’ ","aliases":["diamond_shape_with_a_dot_inside"]},{"emoji":"โ™ฆ๏ธ","aliases":["diamonds"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฌ","aliases":["diego_garcia"]},{"emoji":"๐Ÿ˜ž","aliases":["disappointed"]},{"emoji":"๐Ÿ˜ฅ","aliases":["disappointed_relieved"]},{"emoji":"๐Ÿคฟ","aliases":["diving_mask"]},{"emoji":"๐Ÿช”","aliases":["diya_lamp"]},{"emoji":"๐Ÿ’ซ","aliases":["dizzy"]},{"emoji":"๐Ÿ˜ต","aliases":["dizzy_face"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฏ","aliases":["djibouti"]},{"emoji":"๐Ÿงฌ","aliases":["dna"]},{"emoji":"๐Ÿšฏ","aliases":["do_not_litter"]},{"emoji":"๐Ÿถ","aliases":["dog"]},{"emoji":"๐Ÿ•","aliases":["dog2"]},{"emoji":"๐Ÿ’ต","aliases":["dollar"]},{"emoji":"๐ŸŽŽ","aliases":["dolls"]},{"emoji":"๐Ÿฌ","aliases":["dolphin","flipper"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฒ","aliases":["dominica"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ด","aliases":["dominican_republic"]},{"emoji":"๐Ÿšช","aliases":["door"]},{"emoji":"๐Ÿฉ","aliases":["doughnut"]},{"emoji":"๐Ÿ•Š๏ธ","aliases":["dove"]},{"emoji":"๐Ÿ‰","aliases":["dragon"]},{"emoji":"๐Ÿฒ","aliases":["dragon_face"]},{"emoji":"๐Ÿ‘—","aliases":["dress"]},{"emoji":"๐Ÿช","aliases":["dromedary_camel"]},{"emoji":"๐Ÿคค","aliases":["drooling_face"]},{"emoji":"๐Ÿฉธ","aliases":["drop_of_blood"]},{"emoji":"๐Ÿ’ง","aliases":["droplet"]},{"emoji":"๐Ÿฅ","aliases":["drum"]},{"emoji":"๐Ÿฆ†","aliases":["duck"]},{"emoji":"๐ŸฅŸ","aliases":["dumpling"]},{"emoji":"๐Ÿ“€","aliases":["dvd"]},{"emoji":"๐Ÿ“ง","aliases":["e-mail"]},{"emoji":"๐Ÿฆ…","aliases":["eagle"]},{"emoji":"๐Ÿ‘‚","aliases":["ear"]},{"emoji":"๐ŸŒพ","aliases":["ear_of_rice"]},{"emoji":"๐Ÿฆป","aliases":["ear_with_hearing_aid"]},{"emoji":"๐ŸŒ","aliases":["earth_africa"]},{"emoji":"๐ŸŒŽ","aliases":["earth_americas"]},{"emoji":"๐ŸŒ","aliases":["earth_asia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡จ","aliases":["ecuador"]},{"emoji":"๐Ÿฅš","aliases":["egg"]},{"emoji":"๐Ÿ†","aliases":["eggplant"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ฌ","aliases":["egypt"]},{"emoji":"8๏ธโƒฃ","aliases":["eight"]},{"emoji":"โœด๏ธ","aliases":["eight_pointed_black_star"]},{"emoji":"โœณ๏ธ","aliases":["eight_spoked_asterisk"]},{"emoji":"โ๏ธ","aliases":["eject_button"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ป","aliases":["el_salvador"]},{"emoji":"๐Ÿ”Œ","aliases":["electric_plug"]},{"emoji":"๐Ÿ˜","aliases":["elephant"]},{"emoji":"๐Ÿง","aliases":["elf"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["elf_man"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["elf_woman"]},{"emoji":"โœ‰๏ธ","aliases":["email","envelope"]},{"emoji":"๐Ÿ”š","aliases":["end"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ","aliases":["england"]},{"emoji":"๐Ÿ“ฉ","aliases":["envelope_with_arrow"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ถ","aliases":["equatorial_guinea"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ท","aliases":["eritrea"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ธ","aliases":["es"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ช","aliases":["estonia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡น","aliases":["ethiopia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡บ","aliases":["eu","european_union"]},{"emoji":"๐Ÿ’ถ","aliases":["euro"]},{"emoji":"๐Ÿฐ","aliases":["european_castle"]},{"emoji":"๐Ÿค","aliases":["european_post_office"]},{"emoji":"๐ŸŒฒ","aliases":["evergreen_tree"]},{"emoji":"โ—","aliases":["exclamation","heavy_exclamation_mark"]},{"emoji":"๐Ÿคฏ","aliases":["exploding_head"]},{"emoji":"๐Ÿ˜‘","aliases":["expressionless"]},{"emoji":"๐Ÿ‘๏ธ","aliases":["eye"]},{"emoji":"๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ","aliases":["eye_speech_bubble"]},{"emoji":"๐Ÿ‘“","aliases":["eyeglasses"]},{"emoji":"๐Ÿ‘€","aliases":["eyes"]},{"emoji":"๐Ÿค•","aliases":["face_with_head_bandage"]},{"emoji":"๐Ÿค’","aliases":["face_with_thermometer"]},{"emoji":"๐Ÿคฆ","aliases":["facepalm"]},{"emoji":"๐Ÿญ","aliases":["factory"]},{"emoji":"๐Ÿง‘โ€๐Ÿญ","aliases":["factory_worker"]},{"emoji":"๐Ÿงš","aliases":["fairy"]},{"emoji":"๐Ÿงšโ€โ™‚๏ธ","aliases":["fairy_man"]},{"emoji":"๐Ÿงšโ€โ™€๏ธ","aliases":["fairy_woman"]},{"emoji":"๐Ÿง†","aliases":["falafel"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฐ","aliases":["falkland_islands"]},{"emoji":"๐Ÿ‚","aliases":["fallen_leaf"]},{"emoji":"๐Ÿ‘ช","aliases":["family"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฆ","aliases":["family_man_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ง","aliases":["family_man_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_girl_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ","aliases":["family_man_man_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_man_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง","aliases":["family_man_man_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_man_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_man_girl_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_man_woman_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_woman_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_man_woman_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_woman_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_woman_girl_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_woman_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_woman_boy_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_woman_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_woman_girl_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_woman_girl_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_boy_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_woman_woman_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_girl_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_woman_woman_girl_girl"]},{"emoji":"๐Ÿง‘โ€๐ŸŒพ","aliases":["farmer"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ด","aliases":["faroe_islands"]},{"emoji":"โฉ","aliases":["fast_forward"]},{"emoji":"๐Ÿ“ ","aliases":["fax"]},{"emoji":"๐Ÿ˜จ","aliases":["fearful"]},{"emoji":"๐Ÿพ","aliases":["feet","paw_prints"]},{"emoji":"๐Ÿ•ต๏ธโ€โ™€๏ธ","aliases":["female_detective"]},{"emoji":"โ™€๏ธ","aliases":["female_sign"]},{"emoji":"๐ŸŽก","aliases":["ferris_wheel"]},{"emoji":"โ›ด๏ธ","aliases":["ferry"]},{"emoji":"๐Ÿ‘","aliases":["field_hockey"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฏ","aliases":["fiji"]},{"emoji":"๐Ÿ—„๏ธ","aliases":["file_cabinet"]},{"emoji":"๐Ÿ“","aliases":["file_folder"]},{"emoji":"๐Ÿ“ฝ๏ธ","aliases":["film_projector"]},{"emoji":"๐ŸŽž๏ธ","aliases":["film_strip"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฎ","aliases":["finland"]},{"emoji":"๐Ÿ”ฅ","aliases":["fire"]},{"emoji":"๐Ÿš’","aliases":["fire_engine"]},{"emoji":"๐Ÿงฏ","aliases":["fire_extinguisher"]},{"emoji":"๐Ÿงจ","aliases":["firecracker"]},{"emoji":"๐Ÿง‘โ€๐Ÿš’","aliases":["firefighter"]},{"emoji":"๐ŸŽ†","aliases":["fireworks"]},{"emoji":"๐ŸŒ“","aliases":["first_quarter_moon"]},{"emoji":"๐ŸŒ›","aliases":["first_quarter_moon_with_face"]},{"emoji":"๐ŸŸ","aliases":["fish"]},{"emoji":"๐Ÿฅ","aliases":["fish_cake"]},{"emoji":"๐ŸŽฃ","aliases":["fishing_pole_and_fish"]},{"emoji":"๐Ÿค›","aliases":["fist_left"]},{"emoji":"๐Ÿ‘Š","aliases":["fist_oncoming","facepunch","punch"]},{"emoji":"โœŠ","aliases":["fist_raised","fist"]},{"emoji":"๐Ÿคœ","aliases":["fist_right"]},{"emoji":"5๏ธโƒฃ","aliases":["five"]},{"emoji":"๐ŸŽ","aliases":["flags"]},{"emoji":"๐Ÿฆฉ","aliases":["flamingo"]},{"emoji":"๐Ÿ”ฆ","aliases":["flashlight"]},{"emoji":"๐Ÿฅฟ","aliases":["flat_shoe"]},{"emoji":"โšœ๏ธ","aliases":["fleur_de_lis"]},{"emoji":"๐Ÿ›ฌ","aliases":["flight_arrival"]},{"emoji":"๐Ÿ›ซ","aliases":["flight_departure"]},{"emoji":"๐Ÿ’พ","aliases":["floppy_disk"]},{"emoji":"๐ŸŽด","aliases":["flower_playing_cards"]},{"emoji":"๐Ÿ˜ณ","aliases":["flushed"]},{"emoji":"๐Ÿฅ","aliases":["flying_disc"]},{"emoji":"๐Ÿ›ธ","aliases":["flying_saucer"]},{"emoji":"๐ŸŒซ๏ธ","aliases":["fog"]},{"emoji":"๐ŸŒ","aliases":["foggy"]},{"emoji":"๐Ÿฆถ","aliases":["foot"]},{"emoji":"๐Ÿˆ","aliases":["football"]},{"emoji":"๐Ÿ‘ฃ","aliases":["footprints"]},{"emoji":"๐Ÿด","aliases":["fork_and_knife"]},{"emoji":"๐Ÿฅ ","aliases":["fortune_cookie"]},{"emoji":"โ›ฒ","aliases":["fountain"]},{"emoji":"๐Ÿ–‹๏ธ","aliases":["fountain_pen"]},{"emoji":"4๏ธโƒฃ","aliases":["four"]},{"emoji":"๐Ÿ€","aliases":["four_leaf_clover"]},{"emoji":"๐ŸฆŠ","aliases":["fox_face"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ท","aliases":["fr"]},{"emoji":"๐Ÿ–ผ๏ธ","aliases":["framed_picture"]},{"emoji":"๐Ÿ†“","aliases":["free"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ซ","aliases":["french_guiana"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ซ","aliases":["french_polynesia"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ซ","aliases":["french_southern_territories"]},{"emoji":"๐Ÿณ","aliases":["fried_egg"]},{"emoji":"๐Ÿค","aliases":["fried_shrimp"]},{"emoji":"๐ŸŸ","aliases":["fries"]},{"emoji":"๐Ÿธ","aliases":["frog"]},{"emoji":"๐Ÿ˜ฆ","aliases":["frowning"]},{"emoji":"โ˜น๏ธ","aliases":["frowning_face"]},{"emoji":"๐Ÿ™โ€โ™‚๏ธ","aliases":["frowning_man"]},{"emoji":"๐Ÿ™","aliases":["frowning_person"]},{"emoji":"๐Ÿ™โ€โ™€๏ธ","aliases":["frowning_woman"]},{"emoji":"โ›ฝ","aliases":["fuelpump"]},{"emoji":"๐ŸŒ•","aliases":["full_moon"]},{"emoji":"๐ŸŒ","aliases":["full_moon_with_face"]},{"emoji":"โšฑ๏ธ","aliases":["funeral_urn"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฆ","aliases":["gabon"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฒ","aliases":["gambia"]},{"emoji":"๐ŸŽฒ","aliases":["game_die"]},{"emoji":"๐Ÿง„","aliases":["garlic"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ง","aliases":["gb","uk"]},{"emoji":"โš™๏ธ","aliases":["gear"]},{"emoji":"๐Ÿ’Ž","aliases":["gem"]},{"emoji":"โ™Š","aliases":["gemini"]},{"emoji":"๐Ÿงž","aliases":["genie"]},{"emoji":"๐Ÿงžโ€โ™‚๏ธ","aliases":["genie_man"]},{"emoji":"๐Ÿงžโ€โ™€๏ธ","aliases":["genie_woman"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ช","aliases":["georgia"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ญ","aliases":["ghana"]},{"emoji":"๐Ÿ‘ป","aliases":["ghost"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฎ","aliases":["gibraltar"]},{"emoji":"๐ŸŽ","aliases":["gift"]},{"emoji":"๐Ÿ’","aliases":["gift_heart"]},{"emoji":"๐Ÿฆ’","aliases":["giraffe"]},{"emoji":"๐Ÿ‘ง","aliases":["girl"]},{"emoji":"๐ŸŒ","aliases":["globe_with_meridians"]},{"emoji":"๐Ÿงค","aliases":["gloves"]},{"emoji":"๐Ÿฅ…","aliases":["goal_net"]},{"emoji":"๐Ÿ","aliases":["goat"]},{"emoji":"๐Ÿฅฝ","aliases":["goggles"]},{"emoji":"โ›ณ","aliases":["golf"]},{"emoji":"๐ŸŒ๏ธ","aliases":["golfing"]},{"emoji":"๐ŸŒ๏ธโ€โ™‚๏ธ","aliases":["golfing_man"]},{"emoji":"๐ŸŒ๏ธโ€โ™€๏ธ","aliases":["golfing_woman"]},{"emoji":"๐Ÿฆ","aliases":["gorilla"]},{"emoji":"๐Ÿ‡","aliases":["grapes"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ท","aliases":["greece"]},{"emoji":"๐Ÿ","aliases":["green_apple"]},{"emoji":"๐Ÿ“—","aliases":["green_book"]},{"emoji":"๐ŸŸข","aliases":["green_circle"]},{"emoji":"๐Ÿ’š","aliases":["green_heart"]},{"emoji":"๐Ÿฅ—","aliases":["green_salad"]},{"emoji":"๐ŸŸฉ","aliases":["green_square"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฑ","aliases":["greenland"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฉ","aliases":["grenada"]},{"emoji":"โ•","aliases":["grey_exclamation"]},{"emoji":"โ”","aliases":["grey_question"]},{"emoji":"๐Ÿ˜ฌ","aliases":["grimacing"]},{"emoji":"๐Ÿ˜","aliases":["grin"]},{"emoji":"๐Ÿ˜€","aliases":["grinning"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ต","aliases":["guadeloupe"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡บ","aliases":["guam"]},{"emoji":"๐Ÿ’‚","aliases":["guard"]},{"emoji":"๐Ÿ’‚โ€โ™‚๏ธ","aliases":["guardsman"]},{"emoji":"๐Ÿ’‚โ€โ™€๏ธ","aliases":["guardswoman"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡น","aliases":["guatemala"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฌ","aliases":["guernsey"]},{"emoji":"๐Ÿฆฎ","aliases":["guide_dog"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ณ","aliases":["guinea"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ผ","aliases":["guinea_bissau"]},{"emoji":"๐ŸŽธ","aliases":["guitar"]},{"emoji":"๐Ÿ”ซ","aliases":["gun"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡พ","aliases":["guyana"]},{"emoji":"๐Ÿ’‡","aliases":["haircut"]},{"emoji":"๐Ÿ’‡โ€โ™‚๏ธ","aliases":["haircut_man"]},{"emoji":"๐Ÿ’‡โ€โ™€๏ธ","aliases":["haircut_woman"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡น","aliases":["haiti"]},{"emoji":"๐Ÿ”","aliases":["hamburger"]},{"emoji":"๐Ÿ”จ","aliases":["hammer"]},{"emoji":"โš’๏ธ","aliases":["hammer_and_pick"]},{"emoji":"๐Ÿ› ๏ธ","aliases":["hammer_and_wrench"]},{"emoji":"๐Ÿน","aliases":["hamster"]},{"emoji":"โœ‹","aliases":["hand","raised_hand"]},{"emoji":"๐Ÿคญ","aliases":["hand_over_mouth"]},{"emoji":"๐Ÿ‘œ","aliases":["handbag"]},{"emoji":"๐Ÿคพ","aliases":["handball_person"]},{"emoji":"๐Ÿค","aliases":["handshake"]},{"emoji":"๐Ÿ’ฉ","aliases":["hankey","poop","shit"]},{"emoji":"#๏ธโƒฃ","aliases":["hash"]},{"emoji":"๐Ÿฅ","aliases":["hatched_chick"]},{"emoji":"๐Ÿฃ","aliases":["hatching_chick"]},{"emoji":"๐ŸŽง","aliases":["headphones"]},{"emoji":"๐Ÿง‘โ€โš•๏ธ","aliases":["health_worker"]},{"emoji":"๐Ÿ™‰","aliases":["hear_no_evil"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ฒ","aliases":["heard_mcdonald_islands"]},{"emoji":"โค๏ธ","aliases":["heart"]},{"emoji":"๐Ÿ’Ÿ","aliases":["heart_decoration"]},{"emoji":"๐Ÿ˜","aliases":["heart_eyes"]},{"emoji":"๐Ÿ˜ป","aliases":["heart_eyes_cat"]},{"emoji":"๐Ÿ’“","aliases":["heartbeat"]},{"emoji":"๐Ÿ’—","aliases":["heartpulse"]},{"emoji":"โ™ฅ๏ธ","aliases":["hearts"]},{"emoji":"โœ”๏ธ","aliases":["heavy_check_mark"]},{"emoji":"โž—","aliases":["heavy_division_sign"]},{"emoji":"๐Ÿ’ฒ","aliases":["heavy_dollar_sign"]},{"emoji":"โฃ๏ธ","aliases":["heavy_heart_exclamation"]},{"emoji":"โž–","aliases":["heavy_minus_sign"]},{"emoji":"โœ–๏ธ","aliases":["heavy_multiplication_x"]},{"emoji":"โž•","aliases":["heavy_plus_sign"]},{"emoji":"๐Ÿฆ”","aliases":["hedgehog"]},{"emoji":"๐Ÿš","aliases":["helicopter"]},{"emoji":"๐ŸŒฟ","aliases":["herb"]},{"emoji":"๐ŸŒบ","aliases":["hibiscus"]},{"emoji":"๐Ÿ”†","aliases":["high_brightness"]},{"emoji":"๐Ÿ‘ ","aliases":["high_heel"]},{"emoji":"๐Ÿฅพ","aliases":["hiking_boot"]},{"emoji":"๐Ÿ›•","aliases":["hindu_temple"]},{"emoji":"๐Ÿฆ›","aliases":["hippopotamus"]},{"emoji":"๐Ÿ”ช","aliases":["hocho","knife"]},{"emoji":"๐Ÿ•ณ๏ธ","aliases":["hole"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ณ","aliases":["honduras"]},{"emoji":"๐Ÿฏ","aliases":["honey_pot"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ฐ","aliases":["hong_kong"]},{"emoji":"๐Ÿด","aliases":["horse"]},{"emoji":"๐Ÿ‡","aliases":["horse_racing"]},{"emoji":"๐Ÿฅ","aliases":["hospital"]},{"emoji":"๐Ÿฅต","aliases":["hot_face"]},{"emoji":"๐ŸŒถ๏ธ","aliases":["hot_pepper"]},{"emoji":"๐ŸŒญ","aliases":["hotdog"]},{"emoji":"๐Ÿจ","aliases":["hotel"]},{"emoji":"โ™จ๏ธ","aliases":["hotsprings"]},{"emoji":"โŒ›","aliases":["hourglass"]},{"emoji":"โณ","aliases":["hourglass_flowing_sand"]},{"emoji":"๐Ÿ ","aliases":["house"]},{"emoji":"๐Ÿก","aliases":["house_with_garden"]},{"emoji":"๐Ÿ˜๏ธ","aliases":["houses"]},{"emoji":"๐Ÿค—","aliases":["hugs"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡บ","aliases":["hungary"]},{"emoji":"๐Ÿ˜ฏ","aliases":["hushed"]},{"emoji":"๐Ÿจ","aliases":["ice_cream"]},{"emoji":"๐ŸงŠ","aliases":["ice_cube"]},{"emoji":"๐Ÿ’","aliases":["ice_hockey"]},{"emoji":"โ›ธ๏ธ","aliases":["ice_skate"]},{"emoji":"๐Ÿฆ","aliases":["icecream"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ธ","aliases":["iceland"]},{"emoji":"๐Ÿ†”","aliases":["id"]},{"emoji":"๐Ÿ‰","aliases":["ideograph_advantage"]},{"emoji":"๐Ÿ‘ฟ","aliases":["imp"]},{"emoji":"๐Ÿ“ฅ","aliases":["inbox_tray"]},{"emoji":"๐Ÿ“จ","aliases":["incoming_envelope"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ณ","aliases":["india"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฉ","aliases":["indonesia"]},{"emoji":"โ™พ๏ธ","aliases":["infinity"]},{"emoji":"โ„น๏ธ","aliases":["information_source"]},{"emoji":"๐Ÿ˜‡","aliases":["innocent"]},{"emoji":"โ‰๏ธ","aliases":["interrobang"]},{"emoji":"๐Ÿ“ฑ","aliases":["iphone"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ท","aliases":["iran"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ถ","aliases":["iraq"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ช","aliases":["ireland"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฒ","aliases":["isle_of_man"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฑ","aliases":["israel"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡น","aliases":["it"]},{"emoji":"๐Ÿฎ","aliases":["izakaya_lantern","lantern"]},{"emoji":"๐ŸŽƒ","aliases":["jack_o_lantern"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ฒ","aliases":["jamaica"]},{"emoji":"๐Ÿ—พ","aliases":["japan"]},{"emoji":"๐Ÿฏ","aliases":["japanese_castle"]},{"emoji":"๐Ÿ‘บ","aliases":["japanese_goblin"]},{"emoji":"๐Ÿ‘น","aliases":["japanese_ogre"]},{"emoji":"๐Ÿ‘–","aliases":["jeans"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ช","aliases":["jersey"]},{"emoji":"๐Ÿงฉ","aliases":["jigsaw"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ด","aliases":["jordan"]},{"emoji":"๐Ÿ˜‚","aliases":["joy"]},{"emoji":"๐Ÿ˜น","aliases":["joy_cat"]},{"emoji":"๐Ÿ•น๏ธ","aliases":["joystick"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ต","aliases":["jp"]},{"emoji":"๐Ÿง‘โ€โš–๏ธ","aliases":["judge"]},{"emoji":"๐Ÿคน","aliases":["juggling_person"]},{"emoji":"๐Ÿ•‹","aliases":["kaaba"]},{"emoji":"๐Ÿฆ˜","aliases":["kangaroo"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฟ","aliases":["kazakhstan"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ช","aliases":["kenya"]},{"emoji":"๐Ÿ”‘","aliases":["key"]},{"emoji":"โŒจ๏ธ","aliases":["keyboard"]},{"emoji":"๐Ÿ”Ÿ","aliases":["keycap_ten"]},{"emoji":"๐Ÿ›ด","aliases":["kick_scooter"]},{"emoji":"๐Ÿ‘˜","aliases":["kimono"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฎ","aliases":["kiribati"]},{"emoji":"๐Ÿ’‹","aliases":["kiss"]},{"emoji":"๐Ÿ˜—","aliases":["kissing"]},{"emoji":"๐Ÿ˜ฝ","aliases":["kissing_cat"]},{"emoji":"๐Ÿ˜š","aliases":["kissing_closed_eyes"]},{"emoji":"๐Ÿ˜˜","aliases":["kissing_heart"]},{"emoji":"๐Ÿ˜™","aliases":["kissing_smiling_eyes"]},{"emoji":"๐Ÿช","aliases":["kite"]},{"emoji":"๐Ÿฅ","aliases":["kiwi_fruit"]},{"emoji":"๐ŸงŽโ€โ™‚๏ธ","aliases":["kneeling_man"]},{"emoji":"๐ŸงŽ","aliases":["kneeling_person"]},{"emoji":"๐ŸงŽโ€โ™€๏ธ","aliases":["kneeling_woman"]},{"emoji":"๐Ÿจ","aliases":["koala"]},{"emoji":"๐Ÿˆ","aliases":["koko"]},{"emoji":"๐Ÿ‡ฝ๐Ÿ‡ฐ","aliases":["kosovo"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ท","aliases":["kr"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ผ","aliases":["kuwait"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฌ","aliases":["kyrgyzstan"]},{"emoji":"๐Ÿฅผ","aliases":["lab_coat"]},{"emoji":"๐Ÿท๏ธ","aliases":["label"]},{"emoji":"๐Ÿฅ","aliases":["lacrosse"]},{"emoji":"๐Ÿž","aliases":["lady_beetle"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฆ","aliases":["laos"]},{"emoji":"๐Ÿ”ต","aliases":["large_blue_circle"]},{"emoji":"๐Ÿ”ท","aliases":["large_blue_diamond"]},{"emoji":"๐Ÿ”ถ","aliases":["large_orange_diamond"]},{"emoji":"๐ŸŒ—","aliases":["last_quarter_moon"]},{"emoji":"๐ŸŒœ","aliases":["last_quarter_moon_with_face"]},{"emoji":"โœ๏ธ","aliases":["latin_cross"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ป","aliases":["latvia"]},{"emoji":"๐Ÿ˜†","aliases":["laughing","satisfied","laugh"]},{"emoji":"๐Ÿฅฌ","aliases":["leafy_green"]},{"emoji":"๐Ÿƒ","aliases":["leaves"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ง","aliases":["lebanon"]},{"emoji":"๐Ÿ“’","aliases":["ledger"]},{"emoji":"๐Ÿ›…","aliases":["left_luggage"]},{"emoji":"โ†”๏ธ","aliases":["left_right_arrow"]},{"emoji":"๐Ÿ—จ๏ธ","aliases":["left_speech_bubble"]},{"emoji":"โ†ฉ๏ธ","aliases":["leftwards_arrow_with_hook"]},{"emoji":"๐Ÿฆต","aliases":["leg"]},{"emoji":"๐Ÿ‹","aliases":["lemon"]},{"emoji":"โ™Œ","aliases":["leo"]},{"emoji":"๐Ÿ†","aliases":["leopard"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ธ","aliases":["lesotho"]},{"emoji":"๐ŸŽš๏ธ","aliases":["level_slider"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ท","aliases":["liberia"]},{"emoji":"โ™Ž","aliases":["libra"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡พ","aliases":["libya"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฎ","aliases":["liechtenstein"]},{"emoji":"๐Ÿšˆ","aliases":["light_rail"]},{"emoji":"๐Ÿ”—","aliases":["link"]},{"emoji":"๐Ÿฆ","aliases":["lion"]},{"emoji":"๐Ÿ‘„","aliases":["lips"]},{"emoji":"๐Ÿ’„","aliases":["lipstick"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡น","aliases":["lithuania"]},{"emoji":"๐ŸฆŽ","aliases":["lizard"]},{"emoji":"๐Ÿฆ™","aliases":["llama"]},{"emoji":"๐Ÿฆž","aliases":["lobster"]},{"emoji":"๐Ÿ”’","aliases":["lock"]},{"emoji":"๐Ÿ”","aliases":["lock_with_ink_pen"]},{"emoji":"๐Ÿญ","aliases":["lollipop"]},{"emoji":"โžฟ","aliases":["loop"]},{"emoji":"๐Ÿงด","aliases":["lotion_bottle"]},{"emoji":"๐Ÿง˜","aliases":["lotus_position"]},{"emoji":"๐Ÿง˜โ€โ™‚๏ธ","aliases":["lotus_position_man"]},{"emoji":"๐Ÿง˜โ€โ™€๏ธ","aliases":["lotus_position_woman"]},{"emoji":"๐Ÿ”Š","aliases":["loud_sound"]},{"emoji":"๐Ÿ“ข","aliases":["loudspeaker"]},{"emoji":"๐Ÿฉ","aliases":["love_hotel"]},{"emoji":"๐Ÿ’Œ","aliases":["love_letter"]},{"emoji":"๐ŸคŸ","aliases":["love_you_gesture"]},{"emoji":"๐Ÿ”…","aliases":["low_brightness"]},{"emoji":"๐Ÿงณ","aliases":["luggage"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡บ","aliases":["luxembourg"]},{"emoji":"๐Ÿคฅ","aliases":["lying_face"]},{"emoji":"โ“‚๏ธ","aliases":["m"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ด","aliases":["macau"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฐ","aliases":["macedonia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฌ","aliases":["madagascar"]},{"emoji":"๐Ÿ”","aliases":["mag"]},{"emoji":"๐Ÿ”Ž","aliases":["mag_right"]},{"emoji":"๐Ÿง™","aliases":["mage"]},{"emoji":"๐Ÿง™โ€โ™‚๏ธ","aliases":["mage_man"]},{"emoji":"๐Ÿง™โ€โ™€๏ธ","aliases":["mage_woman"]},{"emoji":"๐Ÿงฒ","aliases":["magnet"]},{"emoji":"๐Ÿ€„","aliases":["mahjong"]},{"emoji":"๐Ÿ“ซ","aliases":["mailbox"]},{"emoji":"๐Ÿ“ช","aliases":["mailbox_closed"]},{"emoji":"๐Ÿ“ฌ","aliases":["mailbox_with_mail"]},{"emoji":"๐Ÿ“ญ","aliases":["mailbox_with_no_mail"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ผ","aliases":["malawi"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡พ","aliases":["malaysia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ป","aliases":["maldives"]},{"emoji":"๐Ÿ•ต๏ธโ€โ™‚๏ธ","aliases":["male_detective"]},{"emoji":"โ™‚๏ธ","aliases":["male_sign"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฑ","aliases":["mali"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡น","aliases":["malta"]},{"emoji":"๐Ÿ‘จ","aliases":["man"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽจ","aliases":["man_artist"]},{"emoji":"๐Ÿ‘จโ€๐Ÿš€","aliases":["man_astronaut"]},{"emoji":"๐Ÿคธโ€โ™‚๏ธ","aliases":["man_cartwheeling"]},{"emoji":"๐Ÿ‘จโ€๐Ÿณ","aliases":["man_cook"]},{"emoji":"๐Ÿ•บ","aliases":["man_dancing"]},{"emoji":"๐Ÿคฆโ€โ™‚๏ธ","aliases":["man_facepalming"]},{"emoji":"๐Ÿ‘จโ€๐Ÿญ","aliases":["man_factory_worker"]},{"emoji":"๐Ÿ‘จโ€๐ŸŒพ","aliases":["man_farmer"]},{"emoji":"๐Ÿ‘จโ€๐Ÿš’","aliases":["man_firefighter"]},{"emoji":"๐Ÿ‘จโ€โš•๏ธ","aliases":["man_health_worker"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฝ","aliases":["man_in_manual_wheelchair"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆผ","aliases":["man_in_motorized_wheelchair"]},{"emoji":"๐Ÿ‘จโ€โš–๏ธ","aliases":["man_judge"]},{"emoji":"๐Ÿคนโ€โ™‚๏ธ","aliases":["man_juggling"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ”ง","aliases":["man_mechanic"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ’ผ","aliases":["man_office_worker"]},{"emoji":"๐Ÿ‘จโ€โœˆ๏ธ","aliases":["man_pilot"]},{"emoji":"๐Ÿคพโ€โ™‚๏ธ","aliases":["man_playing_handball"]},{"emoji":"๐Ÿคฝโ€โ™‚๏ธ","aliases":["man_playing_water_polo"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ”ฌ","aliases":["man_scientist"]},{"emoji":"๐Ÿคทโ€โ™‚๏ธ","aliases":["man_shrugging"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽค","aliases":["man_singer"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽ“","aliases":["man_student"]},{"emoji":"๐Ÿ‘จโ€๐Ÿซ","aliases":["man_teacher"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ’ป","aliases":["man_technologist"]},{"emoji":"๐Ÿ‘ฒ","aliases":["man_with_gua_pi_mao"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฏ","aliases":["man_with_probing_cane"]},{"emoji":"๐Ÿ‘ณโ€โ™‚๏ธ","aliases":["man_with_turban"]},{"emoji":"๐Ÿฅญ","aliases":["mango"]},{"emoji":"๐Ÿ‘ž","aliases":["mans_shoe","shoe"]},{"emoji":"๐Ÿ•ฐ๏ธ","aliases":["mantelpiece_clock"]},{"emoji":"๐Ÿฆฝ","aliases":["manual_wheelchair"]},{"emoji":"๐Ÿ","aliases":["maple_leaf"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ญ","aliases":["marshall_islands"]},{"emoji":"๐Ÿฅ‹","aliases":["martial_arts_uniform"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ถ","aliases":["martinique"]},{"emoji":"๐Ÿ˜ท","aliases":["mask"]},{"emoji":"๐Ÿ’†","aliases":["massage"]},{"emoji":"๐Ÿ’†โ€โ™‚๏ธ","aliases":["massage_man"]},{"emoji":"๐Ÿ’†โ€โ™€๏ธ","aliases":["massage_woman"]},{"emoji":"๐Ÿง‰","aliases":["mate"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ท","aliases":["mauritania"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡บ","aliases":["mauritius"]},{"emoji":"๐Ÿ‡พ๐Ÿ‡น","aliases":["mayotte"]},{"emoji":"๐Ÿ–","aliases":["meat_on_bone"]},{"emoji":"๐Ÿง‘โ€๐Ÿ”ง","aliases":["mechanic"]},{"emoji":"๐Ÿฆพ","aliases":["mechanical_arm"]},{"emoji":"๐Ÿฆฟ","aliases":["mechanical_leg"]},{"emoji":"๐ŸŽ–๏ธ","aliases":["medal_military"]},{"emoji":"๐Ÿ…","aliases":["medal_sports"]},{"emoji":"โš•๏ธ","aliases":["medical_symbol"]},{"emoji":"๐Ÿ“ฃ","aliases":["mega"]},{"emoji":"๐Ÿˆ","aliases":["melon"]},{"emoji":"๐Ÿ“","aliases":["memo","pencil"]},{"emoji":"๐Ÿคผโ€โ™‚๏ธ","aliases":["men_wrestling"]},{"emoji":"๐Ÿ•Ž","aliases":["menorah"]},{"emoji":"๐Ÿšน","aliases":["mens"]},{"emoji":"๐Ÿงœโ€โ™€๏ธ","aliases":["mermaid"]},{"emoji":"๐Ÿงœโ€โ™‚๏ธ","aliases":["merman"]},{"emoji":"๐Ÿงœ","aliases":["merperson"]},{"emoji":"๐Ÿค˜","aliases":["metal"]},{"emoji":"๐Ÿš‡","aliases":["metro"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฝ","aliases":["mexico"]},{"emoji":"๐Ÿฆ ","aliases":["microbe"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฒ","aliases":["micronesia"]},{"emoji":"๐ŸŽค","aliases":["microphone"]},{"emoji":"๐Ÿ”ฌ","aliases":["microscope"]},{"emoji":"๐Ÿ–•","aliases":["middle_finger","fu"]},{"emoji":"๐Ÿฅ›","aliases":["milk_glass"]},{"emoji":"๐ŸŒŒ","aliases":["milky_way"]},{"emoji":"๐Ÿš","aliases":["minibus"]},{"emoji":"๐Ÿ’ฝ","aliases":["minidisc"]},{"emoji":"๐Ÿ“ด","aliases":["mobile_phone_off"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฉ","aliases":["moldova"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡จ","aliases":["monaco"]},{"emoji":"๐Ÿค‘","aliases":["money_mouth_face"]},{"emoji":"๐Ÿ’ธ","aliases":["money_with_wings"]},{"emoji":"๐Ÿ’ฐ","aliases":["moneybag"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ณ","aliases":["mongolia"]},{"emoji":"๐Ÿ’","aliases":["monkey"]},{"emoji":"๐Ÿต","aliases":["monkey_face"]},{"emoji":"๐Ÿง","aliases":["monocle_face"]},{"emoji":"๐Ÿš","aliases":["monorail"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ช","aliases":["montenegro"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ธ","aliases":["montserrat"]},{"emoji":"๐ŸŒ”","aliases":["moon","waxing_gibbous_moon"]},{"emoji":"๐Ÿฅฎ","aliases":["moon_cake"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฆ","aliases":["morocco"]},{"emoji":"๐ŸŽ“","aliases":["mortar_board"]},{"emoji":"๐Ÿ•Œ","aliases":["mosque"]},{"emoji":"๐ŸฆŸ","aliases":["mosquito"]},{"emoji":"๐Ÿ›ฅ๏ธ","aliases":["motor_boat"]},{"emoji":"๐Ÿ›ต","aliases":["motor_scooter"]},{"emoji":"๐Ÿ๏ธ","aliases":["motorcycle"]},{"emoji":"๐Ÿฆผ","aliases":["motorized_wheelchair"]},{"emoji":"๐Ÿ›ฃ๏ธ","aliases":["motorway"]},{"emoji":"๐Ÿ—ป","aliases":["mount_fuji"]},{"emoji":"โ›ฐ๏ธ","aliases":["mountain"]},{"emoji":"๐Ÿšต","aliases":["mountain_bicyclist"]},{"emoji":"๐Ÿšตโ€โ™‚๏ธ","aliases":["mountain_biking_man"]},{"emoji":"๐Ÿšตโ€โ™€๏ธ","aliases":["mountain_biking_woman"]},{"emoji":"๐Ÿš ","aliases":["mountain_cableway"]},{"emoji":"๐Ÿšž","aliases":["mountain_railway"]},{"emoji":"๐Ÿ”๏ธ","aliases":["mountain_snow"]},{"emoji":"๐Ÿญ","aliases":["mouse"]},{"emoji":"๐Ÿ","aliases":["mouse2"]},{"emoji":"๐ŸŽฅ","aliases":["movie_camera"]},{"emoji":"๐Ÿ—ฟ","aliases":["moyai"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฟ","aliases":["mozambique"]},{"emoji":"๐Ÿคถ","aliases":["mrs_claus"]},{"emoji":"๐Ÿ’ช","aliases":["muscle"]},{"emoji":"๐Ÿ„","aliases":["mushroom"]},{"emoji":"๐ŸŽน","aliases":["musical_keyboard"]},{"emoji":"๐ŸŽต","aliases":["musical_note"]},{"emoji":"๐ŸŽผ","aliases":["musical_score"]},{"emoji":"๐Ÿ”‡","aliases":["mute"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฒ","aliases":["myanmar"]},{"emoji":"๐Ÿ’…","aliases":["nail_care"]},{"emoji":"๐Ÿ“›","aliases":["name_badge"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฆ","aliases":["namibia"]},{"emoji":"๐Ÿž๏ธ","aliases":["national_park"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ท","aliases":["nauru"]},{"emoji":"๐Ÿคข","aliases":["nauseated_face"]},{"emoji":"๐Ÿงฟ","aliases":["nazar_amulet"]},{"emoji":"๐Ÿ‘”","aliases":["necktie"]},{"emoji":"โŽ","aliases":["negative_squared_cross_mark"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ต","aliases":["nepal"]},{"emoji":"๐Ÿค“","aliases":["nerd_face"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฑ","aliases":["netherlands"]},{"emoji":"๐Ÿ˜","aliases":["neutral_face"]},{"emoji":"๐Ÿ†•","aliases":["new"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡จ","aliases":["new_caledonia"]},{"emoji":"๐ŸŒ‘","aliases":["new_moon"]},{"emoji":"๐ŸŒš","aliases":["new_moon_with_face"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฟ","aliases":["new_zealand"]},{"emoji":"๐Ÿ“ฐ","aliases":["newspaper"]},{"emoji":"๐Ÿ—ž๏ธ","aliases":["newspaper_roll"]},{"emoji":"โญ๏ธ","aliases":["next_track_button"]},{"emoji":"๐Ÿ†–","aliases":["ng"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฎ","aliases":["nicaragua"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ช","aliases":["niger"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฌ","aliases":["nigeria"]},{"emoji":"๐ŸŒƒ","aliases":["night_with_stars"]},{"emoji":"9๏ธโƒฃ","aliases":["nine"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡บ","aliases":["niue"]},{"emoji":"๐Ÿ”•","aliases":["no_bell"]},{"emoji":"๐Ÿšณ","aliases":["no_bicycles"]},{"emoji":"โ›”","aliases":["no_entry"]},{"emoji":"๐Ÿšซ","aliases":["no_entry_sign"]},{"emoji":"๐Ÿ™…","aliases":["no_good"]},{"emoji":"๐Ÿ™…โ€โ™‚๏ธ","aliases":["no_good_man","ng_man"]},{"emoji":"๐Ÿ™…โ€โ™€๏ธ","aliases":["no_good_woman","ng_woman"]},{"emoji":"๐Ÿ“ต","aliases":["no_mobile_phones"]},{"emoji":"๐Ÿ˜ถ","aliases":["no_mouth"]},{"emoji":"๐Ÿšท","aliases":["no_pedestrians"]},{"emoji":"๐Ÿšญ","aliases":["no_smoking"]},{"emoji":"๐Ÿšฑ","aliases":["non-potable_water"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ซ","aliases":["norfolk_island"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ต","aliases":["north_korea"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ต","aliases":["northern_mariana_islands"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ด","aliases":["norway"]},{"emoji":"๐Ÿ‘ƒ","aliases":["nose"]},{"emoji":"๐Ÿ““","aliases":["notebook"]},{"emoji":"๐Ÿ“”","aliases":["notebook_with_decorative_cover"]},{"emoji":"๐ŸŽถ","aliases":["notes"]},{"emoji":"๐Ÿ”ฉ","aliases":["nut_and_bolt"]},{"emoji":"โญ•","aliases":["o"]},{"emoji":"๐Ÿ…พ๏ธ","aliases":["o2"]},{"emoji":"๐ŸŒŠ","aliases":["ocean"]},{"emoji":"๐Ÿ™","aliases":["octopus"]},{"emoji":"๐Ÿข","aliases":["oden"]},{"emoji":"๐Ÿข","aliases":["office"]},{"emoji":"๐Ÿง‘โ€๐Ÿ’ผ","aliases":["office_worker"]},{"emoji":"๐Ÿ›ข๏ธ","aliases":["oil_drum"]},{"emoji":"๐Ÿ†—","aliases":["ok"]},{"emoji":"๐Ÿ‘Œ","aliases":["ok_hand"]},{"emoji":"๐Ÿ™†โ€โ™‚๏ธ","aliases":["ok_man"]},{"emoji":"๐Ÿ™†","aliases":["ok_person"]},{"emoji":"๐Ÿ™†โ€โ™€๏ธ","aliases":["ok_woman"]},{"emoji":"๐Ÿ—๏ธ","aliases":["old_key"]},{"emoji":"๐Ÿง“","aliases":["older_adult"]},{"emoji":"๐Ÿ‘ด","aliases":["older_man"]},{"emoji":"๐Ÿ‘ต","aliases":["older_woman"]},{"emoji":"๐Ÿ•‰๏ธ","aliases":["om"]},{"emoji":"๐Ÿ‡ด๐Ÿ‡ฒ","aliases":["oman"]},{"emoji":"๐Ÿ”›","aliases":["on"]},{"emoji":"๐Ÿš˜","aliases":["oncoming_automobile"]},{"emoji":"๐Ÿš","aliases":["oncoming_bus"]},{"emoji":"๐Ÿš”","aliases":["oncoming_police_car"]},{"emoji":"๐Ÿš–","aliases":["oncoming_taxi"]},{"emoji":"1๏ธโƒฃ","aliases":["one"]},{"emoji":"๐Ÿฉฑ","aliases":["one_piece_swimsuit"]},{"emoji":"๐Ÿง…","aliases":["onion"]},{"emoji":"๐Ÿ“‚","aliases":["open_file_folder"]},{"emoji":"๐Ÿ‘","aliases":["open_hands"]},{"emoji":"๐Ÿ˜ฎ","aliases":["open_mouth"]},{"emoji":"โ˜‚๏ธ","aliases":["open_umbrella"]},{"emoji":"โ›Ž","aliases":["ophiuchus"]},{"emoji":"๐Ÿ“™","aliases":["orange_book"]},{"emoji":"๐ŸŸ ","aliases":["orange_circle"]},{"emoji":"๐Ÿงก","aliases":["orange_heart"]},{"emoji":"๐ŸŸง","aliases":["orange_square"]},{"emoji":"๐Ÿฆง","aliases":["orangutan"]},{"emoji":"โ˜ฆ๏ธ","aliases":["orthodox_cross"]},{"emoji":"๐Ÿฆฆ","aliases":["otter"]},{"emoji":"๐Ÿ“ค","aliases":["outbox_tray"]},{"emoji":"๐Ÿฆ‰","aliases":["owl"]},{"emoji":"๐Ÿ‚","aliases":["ox"]},{"emoji":"๐Ÿฆช","aliases":["oyster"]},{"emoji":"๐Ÿ“ฆ","aliases":["package"]},{"emoji":"๐Ÿ“„","aliases":["page_facing_up"]},{"emoji":"๐Ÿ“ƒ","aliases":["page_with_curl"]},{"emoji":"๐Ÿ“Ÿ","aliases":["pager"]},{"emoji":"๐Ÿ–Œ๏ธ","aliases":["paintbrush"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฐ","aliases":["pakistan"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ผ","aliases":["palau"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ธ","aliases":["palestinian_territories"]},{"emoji":"๐ŸŒด","aliases":["palm_tree"]},{"emoji":"๐Ÿคฒ","aliases":["palms_up_together"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฆ","aliases":["panama"]},{"emoji":"๐Ÿฅž","aliases":["pancakes"]},{"emoji":"๐Ÿผ","aliases":["panda_face"]},{"emoji":"๐Ÿ“Ž","aliases":["paperclip"]},{"emoji":"๐Ÿ–‡๏ธ","aliases":["paperclips"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฌ","aliases":["papua_new_guinea"]},{"emoji":"๐Ÿช‚","aliases":["parachute"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡พ","aliases":["paraguay"]},{"emoji":"โ›ฑ๏ธ","aliases":["parasol_on_ground"]},{"emoji":"๐Ÿ…ฟ๏ธ","aliases":["parking"]},{"emoji":"๐Ÿฆœ","aliases":["parrot"]},{"emoji":"ใ€ฝ๏ธ","aliases":["part_alternation_mark"]},{"emoji":"โ›…","aliases":["partly_sunny"]},{"emoji":"๐Ÿฅณ","aliases":["partying_face"]},{"emoji":"๐Ÿ›ณ๏ธ","aliases":["passenger_ship"]},{"emoji":"๐Ÿ›‚","aliases":["passport_control"]},{"emoji":"โธ๏ธ","aliases":["pause_button"]},{"emoji":"โ˜ฎ๏ธ","aliases":["peace_symbol"]},{"emoji":"๐Ÿ‘","aliases":["peach"]},{"emoji":"๐Ÿฆš","aliases":["peacock"]},{"emoji":"๐Ÿฅœ","aliases":["peanuts"]},{"emoji":"๐Ÿ","aliases":["pear"]},{"emoji":"๐Ÿ–Š๏ธ","aliases":["pen"]},{"emoji":"โœ๏ธ","aliases":["pencil2"]},{"emoji":"๐Ÿง","aliases":["penguin"]},{"emoji":"๐Ÿ˜”","aliases":["pensive"]},{"emoji":"๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘","aliases":["people_holding_hands"]},{"emoji":"๐ŸŽญ","aliases":["performing_arts"]},{"emoji":"๐Ÿ˜ฃ","aliases":["persevere"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฒ","aliases":["person_bald"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฑ","aliases":["person_curly_hair"]},{"emoji":"๐Ÿคบ","aliases":["person_fencing"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฝ","aliases":["person_in_manual_wheelchair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆผ","aliases":["person_in_motorized_wheelchair"]},{"emoji":"๐Ÿคต","aliases":["person_in_tuxedo"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฐ","aliases":["person_red_hair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆณ","aliases":["person_white_hair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฏ","aliases":["person_with_probing_cane"]},{"emoji":"๐Ÿ‘ณ","aliases":["person_with_turban"]},{"emoji":"๐Ÿ‘ฐ","aliases":["person_with_veil"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ช","aliases":["peru"]},{"emoji":"๐Ÿงซ","aliases":["petri_dish"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ญ","aliases":["philippines"]},{"emoji":"โ˜Ž๏ธ","aliases":["phone","telephone"]},{"emoji":"โ›๏ธ","aliases":["pick"]},{"emoji":"๐Ÿฅง","aliases":["pie"]},{"emoji":"๐Ÿท","aliases":["pig"]},{"emoji":"๐Ÿ–","aliases":["pig2"]},{"emoji":"๐Ÿฝ","aliases":["pig_nose"]},{"emoji":"๐Ÿ’Š","aliases":["pill"]},{"emoji":"๐Ÿง‘โ€โœˆ๏ธ","aliases":["pilot"]},{"emoji":"๐Ÿค","aliases":["pinching_hand"]},{"emoji":"๐Ÿ","aliases":["pineapple"]},{"emoji":"๐Ÿ“","aliases":["ping_pong"]},{"emoji":"๐Ÿดโ€โ˜ ๏ธ","aliases":["pirate_flag"]},{"emoji":"โ™“","aliases":["pisces"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ณ","aliases":["pitcairn_islands"]},{"emoji":"๐Ÿ•","aliases":["pizza"]},{"emoji":"๐Ÿ›","aliases":["place_of_worship"]},{"emoji":"๐Ÿฝ๏ธ","aliases":["plate_with_cutlery"]},{"emoji":"โฏ๏ธ","aliases":["play_or_pause_button"]},{"emoji":"๐Ÿฅบ","aliases":["pleading_face"]},{"emoji":"๐Ÿ‘‡","aliases":["point_down"]},{"emoji":"๐Ÿ‘ˆ","aliases":["point_left"]},{"emoji":"๐Ÿ‘‰","aliases":["point_right"]},{"emoji":"โ˜๏ธ","aliases":["point_up"]},{"emoji":"๐Ÿ‘†","aliases":["point_up_2"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฑ","aliases":["poland"]},{"emoji":"๐Ÿš“","aliases":["police_car"]},{"emoji":"๐Ÿ‘ฎ","aliases":["police_officer","cop"]},{"emoji":"๐Ÿ‘ฎโ€โ™‚๏ธ","aliases":["policeman"]},{"emoji":"๐Ÿ‘ฎโ€โ™€๏ธ","aliases":["policewoman"]},{"emoji":"๐Ÿฉ","aliases":["poodle"]},{"emoji":"๐Ÿฟ","aliases":["popcorn"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡น","aliases":["portugal"]},{"emoji":"๐Ÿฃ","aliases":["post_office"]},{"emoji":"๐Ÿ“ฏ","aliases":["postal_horn"]},{"emoji":"๐Ÿ“ฎ","aliases":["postbox"]},{"emoji":"๐Ÿšฐ","aliases":["potable_water"]},{"emoji":"๐Ÿฅ”","aliases":["potato"]},{"emoji":"๐Ÿ‘","aliases":["pouch"]},{"emoji":"๐Ÿ—","aliases":["poultry_leg"]},{"emoji":"๐Ÿ’ท","aliases":["pound"]},{"emoji":"๐Ÿ˜พ","aliases":["pouting_cat"]},{"emoji":"๐Ÿ™Ž","aliases":["pouting_face"]},{"emoji":"๐Ÿ™Žโ€โ™‚๏ธ","aliases":["pouting_man"]},{"emoji":"๐Ÿ™Žโ€โ™€๏ธ","aliases":["pouting_woman"]},{"emoji":"๐Ÿ™","aliases":["pray"]},{"emoji":"๐Ÿ“ฟ","aliases":["prayer_beads"]},{"emoji":"๐Ÿคฐ","aliases":["pregnant_woman"]},{"emoji":"๐Ÿฅจ","aliases":["pretzel"]},{"emoji":"โฎ๏ธ","aliases":["previous_track_button"]},{"emoji":"๐Ÿคด","aliases":["prince"]},{"emoji":"๐Ÿ‘ธ","aliases":["princess"]},{"emoji":"๐Ÿ–จ๏ธ","aliases":["printer"]},{"emoji":"๐Ÿฆฏ","aliases":["probing_cane"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ท","aliases":["puerto_rico"]},{"emoji":"๐ŸŸฃ","aliases":["purple_circle"]},{"emoji":"๐Ÿ’œ","aliases":["purple_heart"]},{"emoji":"๐ŸŸช","aliases":["purple_square"]},{"emoji":"๐Ÿ‘›","aliases":["purse"]},{"emoji":"๐Ÿ“Œ","aliases":["pushpin"]},{"emoji":"๐Ÿšฎ","aliases":["put_litter_in_its_place"]},{"emoji":"๐Ÿ‡ถ๐Ÿ‡ฆ","aliases":["qatar"]},{"emoji":"โ“","aliases":["question"]},{"emoji":"๐Ÿฐ","aliases":["rabbit"]},{"emoji":"๐Ÿ‡","aliases":["rabbit2"]},{"emoji":"๐Ÿฆ","aliases":["raccoon"]},{"emoji":"๐ŸŽ","aliases":["racehorse"]},{"emoji":"๐ŸŽ๏ธ","aliases":["racing_car"]},{"emoji":"๐Ÿ“ป","aliases":["radio"]},{"emoji":"๐Ÿ”˜","aliases":["radio_button"]},{"emoji":"โ˜ข๏ธ","aliases":["radioactive"]},{"emoji":"๐Ÿ˜ก","aliases":["rage","pout"]},{"emoji":"๐Ÿšƒ","aliases":["railway_car"]},{"emoji":"๐Ÿ›ค๏ธ","aliases":["railway_track"]},{"emoji":"๐ŸŒˆ","aliases":["rainbow"]},{"emoji":"๐Ÿณ๏ธโ€๐ŸŒˆ","aliases":["rainbow_flag"]},{"emoji":"๐Ÿคš","aliases":["raised_back_of_hand"]},{"emoji":"๐Ÿคจ","aliases":["raised_eyebrow"]},{"emoji":"๐Ÿ–๏ธ","aliases":["raised_hand_with_fingers_splayed"]},{"emoji":"๐Ÿ™Œ","aliases":["raised_hands"]},{"emoji":"๐Ÿ™‹","aliases":["raising_hand"]},{"emoji":"๐Ÿ™‹โ€โ™‚๏ธ","aliases":["raising_hand_man"]},{"emoji":"๐Ÿ™‹โ€โ™€๏ธ","aliases":["raising_hand_woman"]},{"emoji":"๐Ÿ","aliases":["ram"]},{"emoji":"๐Ÿœ","aliases":["ramen"]},{"emoji":"๐Ÿ€","aliases":["rat"]},{"emoji":"๐Ÿช’","aliases":["razor"]},{"emoji":"๐Ÿงพ","aliases":["receipt"]},{"emoji":"โบ๏ธ","aliases":["record_button"]},{"emoji":"โ™ป๏ธ","aliases":["recycle"]},{"emoji":"๐Ÿ”ด","aliases":["red_circle"]},{"emoji":"๐Ÿงง","aliases":["red_envelope"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฐ","aliases":["red_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฐ","aliases":["red_haired_woman"]},{"emoji":"๐ŸŸฅ","aliases":["red_square"]},{"emoji":"ยฎ๏ธ","aliases":["registered"]},{"emoji":"โ˜บ๏ธ","aliases":["relaxed"]},{"emoji":"๐Ÿ˜Œ","aliases":["relieved"]},{"emoji":"๐ŸŽ—๏ธ","aliases":["reminder_ribbon"]},{"emoji":"๐Ÿ”","aliases":["repeat"]},{"emoji":"๐Ÿ”‚","aliases":["repeat_one"]},{"emoji":"โ›‘๏ธ","aliases":["rescue_worker_helmet"]},{"emoji":"๐Ÿšป","aliases":["restroom"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ช","aliases":["reunion"]},{"emoji":"๐Ÿ’ž","aliases":["revolving_hearts"]},{"emoji":"โช","aliases":["rewind"]},{"emoji":"๐Ÿฆ","aliases":["rhinoceros"]},{"emoji":"๐ŸŽ€","aliases":["ribbon"]},{"emoji":"๐Ÿš","aliases":["rice"]},{"emoji":"๐Ÿ™","aliases":["rice_ball"]},{"emoji":"๐Ÿ˜","aliases":["rice_cracker"]},{"emoji":"๐ŸŽ‘","aliases":["rice_scene"]},{"emoji":"๐Ÿ—ฏ๏ธ","aliases":["right_anger_bubble"]},{"emoji":"๐Ÿ’","aliases":["ring"]},{"emoji":"๐Ÿช","aliases":["ringed_planet"]},{"emoji":"๐Ÿค–","aliases":["robot"]},{"emoji":"๐Ÿš€","aliases":["rocket"]},{"emoji":"๐Ÿคฃ","aliases":["rofl"]},{"emoji":"๐Ÿ™„","aliases":["roll_eyes"]},{"emoji":"๐Ÿงป","aliases":["roll_of_paper"]},{"emoji":"๐ŸŽข","aliases":["roller_coaster"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ด","aliases":["romania"]},{"emoji":"๐Ÿ“","aliases":["rooster"]},{"emoji":"๐ŸŒน","aliases":["rose"]},{"emoji":"๐Ÿต๏ธ","aliases":["rosette"]},{"emoji":"๐Ÿšจ","aliases":["rotating_light"]},{"emoji":"๐Ÿ“","aliases":["round_pushpin"]},{"emoji":"๐Ÿšฃ","aliases":["rowboat"]},{"emoji":"๐Ÿšฃโ€โ™‚๏ธ","aliases":["rowing_man"]},{"emoji":"๐Ÿšฃโ€โ™€๏ธ","aliases":["rowing_woman"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡บ","aliases":["ru"]},{"emoji":"๐Ÿ‰","aliases":["rugby_football"]},{"emoji":"๐Ÿƒ","aliases":["runner","running"]},{"emoji":"๐Ÿƒโ€โ™‚๏ธ","aliases":["running_man"]},{"emoji":"๐ŸŽฝ","aliases":["running_shirt_with_sash"]},{"emoji":"๐Ÿƒโ€โ™€๏ธ","aliases":["running_woman"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ผ","aliases":["rwanda"]},{"emoji":"๐Ÿˆ‚๏ธ","aliases":["sa"]},{"emoji":"๐Ÿงท","aliases":["safety_pin"]},{"emoji":"๐Ÿฆบ","aliases":["safety_vest"]},{"emoji":"โ™","aliases":["sagittarius"]},{"emoji":"๐Ÿถ","aliases":["sake"]},{"emoji":"๐Ÿง‚","aliases":["salt"]},{"emoji":"๐Ÿ‡ผ๐Ÿ‡ธ","aliases":["samoa"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฒ","aliases":["san_marino"]},{"emoji":"๐Ÿ‘ก","aliases":["sandal"]},{"emoji":"๐Ÿฅช","aliases":["sandwich"]},{"emoji":"๐ŸŽ…","aliases":["santa"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡น","aliases":["sao_tome_principe"]},{"emoji":"๐Ÿฅป","aliases":["sari"]},{"emoji":"๐Ÿ“ก","aliases":["satellite"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฆ","aliases":["saudi_arabia"]},{"emoji":"๐Ÿง–โ€โ™‚๏ธ","aliases":["sauna_man"]},{"emoji":"๐Ÿง–","aliases":["sauna_person"]},{"emoji":"๐Ÿง–โ€โ™€๏ธ","aliases":["sauna_woman"]},{"emoji":"๐Ÿฆ•","aliases":["sauropod"]},{"emoji":"๐ŸŽท","aliases":["saxophone"]},{"emoji":"๐Ÿงฃ","aliases":["scarf"]},{"emoji":"๐Ÿซ","aliases":["school"]},{"emoji":"๐ŸŽ’","aliases":["school_satchel"]},{"emoji":"๐Ÿง‘โ€๐Ÿ”ฌ","aliases":["scientist"]},{"emoji":"โœ‚๏ธ","aliases":["scissors"]},{"emoji":"๐Ÿฆ‚","aliases":["scorpion"]},{"emoji":"โ™","aliases":["scorpius"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ","aliases":["scotland"]},{"emoji":"๐Ÿ˜ฑ","aliases":["scream"]},{"emoji":"๐Ÿ™€","aliases":["scream_cat"]},{"emoji":"๐Ÿ“œ","aliases":["scroll"]},{"emoji":"๐Ÿ’บ","aliases":["seat"]},{"emoji":"ใŠ™๏ธ","aliases":["secret"]},{"emoji":"๐Ÿ™ˆ","aliases":["see_no_evil"]},{"emoji":"๐ŸŒฑ","aliases":["seedling"]},{"emoji":"๐Ÿคณ","aliases":["selfie"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ณ","aliases":["senegal"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ธ","aliases":["serbia"]},{"emoji":"๐Ÿ•โ€๐Ÿฆบ","aliases":["service_dog"]},{"emoji":"7๏ธโƒฃ","aliases":["seven"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡จ","aliases":["seychelles"]},{"emoji":"๐Ÿฅ˜","aliases":["shallow_pan_of_food"]},{"emoji":"โ˜˜๏ธ","aliases":["shamrock"]},{"emoji":"๐Ÿฆˆ","aliases":["shark"]},{"emoji":"๐Ÿง","aliases":["shaved_ice"]},{"emoji":"๐Ÿ‘","aliases":["sheep"]},{"emoji":"๐Ÿš","aliases":["shell"]},{"emoji":"๐Ÿ›ก๏ธ","aliases":["shield"]},{"emoji":"โ›ฉ๏ธ","aliases":["shinto_shrine"]},{"emoji":"๐Ÿšข","aliases":["ship"]},{"emoji":"๐Ÿ‘•","aliases":["shirt","tshirt"]},{"emoji":"๐Ÿ›๏ธ","aliases":["shopping"]},{"emoji":"๐Ÿ›’","aliases":["shopping_cart"]},{"emoji":"๐Ÿฉณ","aliases":["shorts"]},{"emoji":"๐Ÿšฟ","aliases":["shower"]},{"emoji":"๐Ÿฆ","aliases":["shrimp"]},{"emoji":"๐Ÿคท","aliases":["shrug"]},{"emoji":"๐Ÿคซ","aliases":["shushing_face"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฑ","aliases":["sierra_leone"]},{"emoji":"๐Ÿ“ถ","aliases":["signal_strength"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฌ","aliases":["singapore"]},{"emoji":"๐Ÿง‘โ€๐ŸŽค","aliases":["singer"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฝ","aliases":["sint_maarten"]},{"emoji":"6๏ธโƒฃ","aliases":["six"]},{"emoji":"๐Ÿ”ฏ","aliases":["six_pointed_star"]},{"emoji":"๐Ÿ›น","aliases":["skateboard"]},{"emoji":"๐ŸŽฟ","aliases":["ski"]},{"emoji":"โ›ท๏ธ","aliases":["skier"]},{"emoji":"๐Ÿ’€","aliases":["skull"]},{"emoji":"โ˜ ๏ธ","aliases":["skull_and_crossbones"]},{"emoji":"๐Ÿฆจ","aliases":["skunk"]},{"emoji":"๐Ÿ›ท","aliases":["sled"]},{"emoji":"๐Ÿ˜ด","aliases":["sleeping"]},{"emoji":"๐Ÿ›Œ","aliases":["sleeping_bed"]},{"emoji":"๐Ÿ˜ช","aliases":["sleepy"]},{"emoji":"๐Ÿ™","aliases":["slightly_frowning_face"]},{"emoji":"๐Ÿ™‚","aliases":["slightly_smiling_face"]},{"emoji":"๐ŸŽฐ","aliases":["slot_machine"]},{"emoji":"๐Ÿฆฅ","aliases":["sloth"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฐ","aliases":["slovakia"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฎ","aliases":["slovenia"]},{"emoji":"๐Ÿ›ฉ๏ธ","aliases":["small_airplane"]},{"emoji":"๐Ÿ”น","aliases":["small_blue_diamond"]},{"emoji":"๐Ÿ”ธ","aliases":["small_orange_diamond"]},{"emoji":"๐Ÿ”บ","aliases":["small_red_triangle"]},{"emoji":"๐Ÿ”ป","aliases":["small_red_triangle_down"]},{"emoji":"๐Ÿ˜„","aliases":["smile"]},{"emoji":"๐Ÿ˜ธ","aliases":["smile_cat"]},{"emoji":"๐Ÿ˜ƒ","aliases":["smiley"]},{"emoji":"๐Ÿ˜บ","aliases":["smiley_cat"]},{"emoji":"๐Ÿฅฐ","aliases":["smiling_face_with_three_hearts"]},{"emoji":"๐Ÿ˜ˆ","aliases":["smiling_imp"]},{"emoji":"๐Ÿ˜","aliases":["smirk"]},{"emoji":"๐Ÿ˜ผ","aliases":["smirk_cat"]},{"emoji":"๐Ÿšฌ","aliases":["smoking"]},{"emoji":"๐ŸŒ","aliases":["snail"]},{"emoji":"๐Ÿ","aliases":["snake"]},{"emoji":"๐Ÿคง","aliases":["sneezing_face"]},{"emoji":"๐Ÿ‚","aliases":["snowboarder"]},{"emoji":"โ„๏ธ","aliases":["snowflake"]},{"emoji":"โ›„","aliases":["snowman"]},{"emoji":"โ˜ƒ๏ธ","aliases":["snowman_with_snow"]},{"emoji":"๐Ÿงผ","aliases":["soap"]},{"emoji":"๐Ÿ˜ญ","aliases":["sob"]},{"emoji":"โšฝ","aliases":["soccer"]},{"emoji":"๐Ÿงฆ","aliases":["socks"]},{"emoji":"๐ŸฅŽ","aliases":["softball"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ง","aliases":["solomon_islands"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ด","aliases":["somalia"]},{"emoji":"๐Ÿ”œ","aliases":["soon"]},{"emoji":"๐Ÿ†˜","aliases":["sos"]},{"emoji":"๐Ÿ”‰","aliases":["sound"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ฆ","aliases":["south_africa"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ธ","aliases":["south_georgia_south_sandwich_islands"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ธ","aliases":["south_sudan"]},{"emoji":"๐Ÿ‘พ","aliases":["space_invader"]},{"emoji":"โ™ ๏ธ","aliases":["spades"]},{"emoji":"๐Ÿ","aliases":["spaghetti"]},{"emoji":"โ‡๏ธ","aliases":["sparkle"]},{"emoji":"๐ŸŽ‡","aliases":["sparkler"]},{"emoji":"โœจ","aliases":["sparkles"]},{"emoji":"๐Ÿ’–","aliases":["sparkling_heart"]},{"emoji":"๐Ÿ™Š","aliases":["speak_no_evil"]},{"emoji":"๐Ÿ”ˆ","aliases":["speaker"]},{"emoji":"๐Ÿ—ฃ๏ธ","aliases":["speaking_head"]},{"emoji":"๐Ÿ’ฌ","aliases":["speech_balloon"]},{"emoji":"๐Ÿšค","aliases":["speedboat"]},{"emoji":"๐Ÿ•ท๏ธ","aliases":["spider"]},{"emoji":"๐Ÿ•ธ๏ธ","aliases":["spider_web"]},{"emoji":"๐Ÿ—“๏ธ","aliases":["spiral_calendar"]},{"emoji":"๐Ÿ—’๏ธ","aliases":["spiral_notepad"]},{"emoji":"๐Ÿงฝ","aliases":["sponge"]},{"emoji":"๐Ÿฅ„","aliases":["spoon"]},{"emoji":"๐Ÿฆ‘","aliases":["squid"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฐ","aliases":["sri_lanka"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฑ","aliases":["st_barthelemy"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ญ","aliases":["st_helena"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ณ","aliases":["st_kitts_nevis"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡จ","aliases":["st_lucia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ซ","aliases":["st_martin"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฒ","aliases":["st_pierre_miquelon"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡จ","aliases":["st_vincent_grenadines"]},{"emoji":"๐ŸŸ๏ธ","aliases":["stadium"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["standing_man"]},{"emoji":"๐Ÿง","aliases":["standing_person"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["standing_woman"]},{"emoji":"โญ","aliases":["star"]},{"emoji":"๐ŸŒŸ","aliases":["star2"]},{"emoji":"โ˜ช๏ธ","aliases":["star_and_crescent"]},{"emoji":"โœก๏ธ","aliases":["star_of_david"]},{"emoji":"๐Ÿคฉ","aliases":["star_struck"]},{"emoji":"๐ŸŒ ","aliases":["stars"]},{"emoji":"๐Ÿš‰","aliases":["station"]},{"emoji":"๐Ÿ—ฝ","aliases":["statue_of_liberty"]},{"emoji":"๐Ÿš‚","aliases":["steam_locomotive"]},{"emoji":"๐Ÿฉบ","aliases":["stethoscope"]},{"emoji":"๐Ÿฒ","aliases":["stew"]},{"emoji":"โน๏ธ","aliases":["stop_button"]},{"emoji":"๐Ÿ›‘","aliases":["stop_sign"]},{"emoji":"โฑ๏ธ","aliases":["stopwatch"]},{"emoji":"๐Ÿ“","aliases":["straight_ruler"]},{"emoji":"๐Ÿ“","aliases":["strawberry"]},{"emoji":"๐Ÿ˜›","aliases":["stuck_out_tongue"]},{"emoji":"๐Ÿ˜","aliases":["stuck_out_tongue_closed_eyes"]},{"emoji":"๐Ÿ˜œ","aliases":["stuck_out_tongue_winking_eye"]},{"emoji":"๐Ÿง‘โ€๐ŸŽ“","aliases":["student"]},{"emoji":"๐ŸŽ™๏ธ","aliases":["studio_microphone"]},{"emoji":"๐Ÿฅ™","aliases":["stuffed_flatbread"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฉ","aliases":["sudan"]},{"emoji":"๐ŸŒฅ๏ธ","aliases":["sun_behind_large_cloud"]},{"emoji":"๐ŸŒฆ๏ธ","aliases":["sun_behind_rain_cloud"]},{"emoji":"๐ŸŒค๏ธ","aliases":["sun_behind_small_cloud"]},{"emoji":"๐ŸŒž","aliases":["sun_with_face"]},{"emoji":"๐ŸŒป","aliases":["sunflower"]},{"emoji":"๐Ÿ˜Ž","aliases":["sunglasses"]},{"emoji":"โ˜€๏ธ","aliases":["sunny"]},{"emoji":"๐ŸŒ…","aliases":["sunrise"]},{"emoji":"๐ŸŒ„","aliases":["sunrise_over_mountains"]},{"emoji":"๐Ÿฆธ","aliases":["superhero"]},{"emoji":"๐Ÿฆธโ€โ™‚๏ธ","aliases":["superhero_man"]},{"emoji":"๐Ÿฆธโ€โ™€๏ธ","aliases":["superhero_woman"]},{"emoji":"๐Ÿฆน","aliases":["supervillain"]},{"emoji":"๐Ÿฆนโ€โ™‚๏ธ","aliases":["supervillain_man"]},{"emoji":"๐Ÿฆนโ€โ™€๏ธ","aliases":["supervillain_woman"]},{"emoji":"๐Ÿ„","aliases":["surfer"]},{"emoji":"๐Ÿ„โ€โ™‚๏ธ","aliases":["surfing_man"]},{"emoji":"๐Ÿ„โ€โ™€๏ธ","aliases":["surfing_woman"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ท","aliases":["suriname"]},{"emoji":"๐Ÿฃ","aliases":["sushi"]},{"emoji":"๐ŸšŸ","aliases":["suspension_railway"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฏ","aliases":["svalbard_jan_mayen"]},{"emoji":"๐Ÿฆข","aliases":["swan"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฟ","aliases":["swaziland"]},{"emoji":"๐Ÿ˜“","aliases":["sweat"]},{"emoji":"๐Ÿ’ฆ","aliases":["sweat_drops"]},{"emoji":"๐Ÿ˜…","aliases":["sweat_smile"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ช","aliases":["sweden"]},{"emoji":"๐Ÿ ","aliases":["sweet_potato"]},{"emoji":"๐Ÿฉฒ","aliases":["swim_brief"]},{"emoji":"๐ŸŠ","aliases":["swimmer"]},{"emoji":"๐ŸŠโ€โ™‚๏ธ","aliases":["swimming_man"]},{"emoji":"๐ŸŠโ€โ™€๏ธ","aliases":["swimming_woman"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ญ","aliases":["switzerland"]},{"emoji":"๐Ÿ”ฃ","aliases":["symbols"]},{"emoji":"๐Ÿ•","aliases":["synagogue"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡พ","aliases":["syria"]},{"emoji":"๐Ÿ’‰","aliases":["syringe"]},{"emoji":"๐Ÿฆ–","aliases":["t-rex"]},{"emoji":"๐ŸŒฎ","aliases":["taco"]},{"emoji":"๐ŸŽ‰","aliases":["tada","hooray"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ผ","aliases":["taiwan"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฏ","aliases":["tajikistan"]},{"emoji":"๐Ÿฅก","aliases":["takeout_box"]},{"emoji":"๐ŸŽ‹","aliases":["tanabata_tree"]},{"emoji":"๐ŸŠ","aliases":["tangerine","orange","mandarin"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฟ","aliases":["tanzania"]},{"emoji":"โ™‰","aliases":["taurus"]},{"emoji":"๐Ÿš•","aliases":["taxi"]},{"emoji":"๐Ÿต","aliases":["tea"]},{"emoji":"๐Ÿง‘โ€๐Ÿซ","aliases":["teacher"]},{"emoji":"๐Ÿง‘โ€๐Ÿ’ป","aliases":["technologist"]},{"emoji":"๐Ÿงธ","aliases":["teddy_bear"]},{"emoji":"๐Ÿ“ž","aliases":["telephone_receiver"]},{"emoji":"๐Ÿ”ญ","aliases":["telescope"]},{"emoji":"๐ŸŽพ","aliases":["tennis"]},{"emoji":"โ›บ","aliases":["tent"]},{"emoji":"๐Ÿงช","aliases":["test_tube"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ญ","aliases":["thailand"]},{"emoji":"๐ŸŒก๏ธ","aliases":["thermometer"]},{"emoji":"๐Ÿค”","aliases":["thinking"]},{"emoji":"๐Ÿ’ญ","aliases":["thought_balloon"]},{"emoji":"๐Ÿงต","aliases":["thread"]},{"emoji":"3๏ธโƒฃ","aliases":["three"]},{"emoji":"๐ŸŽซ","aliases":["ticket"]},{"emoji":"๐ŸŽŸ๏ธ","aliases":["tickets"]},{"emoji":"๐Ÿฏ","aliases":["tiger"]},{"emoji":"๐Ÿ…","aliases":["tiger2"]},{"emoji":"โฒ๏ธ","aliases":["timer_clock"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฑ","aliases":["timor_leste"]},{"emoji":"๐Ÿ’โ€โ™‚๏ธ","aliases":["tipping_hand_man","sassy_man"]},{"emoji":"๐Ÿ’","aliases":["tipping_hand_person","information_desk_person"]},{"emoji":"๐Ÿ’โ€โ™€๏ธ","aliases":["tipping_hand_woman","sassy_woman"]},{"emoji":"๐Ÿ˜ซ","aliases":["tired_face"]},{"emoji":"โ„ข๏ธ","aliases":["tm"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฌ","aliases":["togo"]},{"emoji":"๐Ÿšฝ","aliases":["toilet"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฐ","aliases":["tokelau"]},{"emoji":"๐Ÿ—ผ","aliases":["tokyo_tower"]},{"emoji":"๐Ÿ…","aliases":["tomato"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ด","aliases":["tonga"]},{"emoji":"๐Ÿ‘…","aliases":["tongue"]},{"emoji":"๐Ÿงฐ","aliases":["toolbox"]},{"emoji":"๐Ÿฆท","aliases":["tooth"]},{"emoji":"๐Ÿ”","aliases":["top"]},{"emoji":"๐ŸŽฉ","aliases":["tophat"]},{"emoji":"๐ŸŒช๏ธ","aliases":["tornado"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ท","aliases":["tr"]},{"emoji":"๐Ÿ–ฒ๏ธ","aliases":["trackball"]},{"emoji":"๐Ÿšœ","aliases":["tractor"]},{"emoji":"๐Ÿšฅ","aliases":["traffic_light"]},{"emoji":"๐Ÿš‹","aliases":["train"]},{"emoji":"๐Ÿš†","aliases":["train2"]},{"emoji":"๐ŸšŠ","aliases":["tram"]},{"emoji":"๐Ÿšฉ","aliases":["triangular_flag_on_post"]},{"emoji":"๐Ÿ“","aliases":["triangular_ruler"]},{"emoji":"๐Ÿ”ฑ","aliases":["trident"]},{"emoji":"๐Ÿ‡น๐Ÿ‡น","aliases":["trinidad_tobago"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฆ","aliases":["tristan_da_cunha"]},{"emoji":"๐Ÿ˜ค","aliases":["triumph"]},{"emoji":"๐ŸšŽ","aliases":["trolleybus"]},{"emoji":"๐Ÿ†","aliases":["trophy"]},{"emoji":"๐Ÿน","aliases":["tropical_drink"]},{"emoji":"๐Ÿ ","aliases":["tropical_fish"]},{"emoji":"๐Ÿšš","aliases":["truck"]},{"emoji":"๐ŸŽบ","aliases":["trumpet"]},{"emoji":"๐ŸŒท","aliases":["tulip"]},{"emoji":"๐Ÿฅƒ","aliases":["tumbler_glass"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ณ","aliases":["tunisia"]},{"emoji":"๐Ÿฆƒ","aliases":["turkey"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฒ","aliases":["turkmenistan"]},{"emoji":"๐Ÿ‡น๐Ÿ‡จ","aliases":["turks_caicos_islands"]},{"emoji":"๐Ÿข","aliases":["turtle"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ป","aliases":["tuvalu"]},{"emoji":"๐Ÿ“บ","aliases":["tv"]},{"emoji":"๐Ÿ”€","aliases":["twisted_rightwards_arrows"]},{"emoji":"2๏ธโƒฃ","aliases":["two"]},{"emoji":"๐Ÿ’•","aliases":["two_hearts"]},{"emoji":"๐Ÿ‘ฌ","aliases":["two_men_holding_hands"]},{"emoji":"๐Ÿ‘ญ","aliases":["two_women_holding_hands"]},{"emoji":"๐Ÿˆน","aliases":["u5272"]},{"emoji":"๐Ÿˆด","aliases":["u5408"]},{"emoji":"๐Ÿˆบ","aliases":["u55b6"]},{"emoji":"๐Ÿˆฏ","aliases":["u6307"]},{"emoji":"๐Ÿˆท๏ธ","aliases":["u6708"]},{"emoji":"๐Ÿˆถ","aliases":["u6709"]},{"emoji":"๐Ÿˆต","aliases":["u6e80"]},{"emoji":"๐Ÿˆš","aliases":["u7121"]},{"emoji":"๐Ÿˆธ","aliases":["u7533"]},{"emoji":"๐Ÿˆฒ","aliases":["u7981"]},{"emoji":"๐Ÿˆณ","aliases":["u7a7a"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฌ","aliases":["uganda"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฆ","aliases":["ukraine"]},{"emoji":"โ˜”","aliases":["umbrella"]},{"emoji":"๐Ÿ˜’","aliases":["unamused"]},{"emoji":"๐Ÿ”ž","aliases":["underage"]},{"emoji":"๐Ÿฆ„","aliases":["unicorn"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ช","aliases":["united_arab_emirates"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ณ","aliases":["united_nations"]},{"emoji":"๐Ÿ”“","aliases":["unlock"]},{"emoji":"๐Ÿ†™","aliases":["up"]},{"emoji":"๐Ÿ™ƒ","aliases":["upside_down_face"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡พ","aliases":["uruguay"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ธ","aliases":["us"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฒ","aliases":["us_outlying_islands"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฎ","aliases":["us_virgin_islands"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฟ","aliases":["uzbekistan"]},{"emoji":"โœŒ๏ธ","aliases":["v"]},{"emoji":"๐Ÿง›","aliases":["vampire"]},{"emoji":"๐Ÿง›โ€โ™‚๏ธ","aliases":["vampire_man"]},{"emoji":"๐Ÿง›โ€โ™€๏ธ","aliases":["vampire_woman"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡บ","aliases":["vanuatu"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฆ","aliases":["vatican_city"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ช","aliases":["venezuela"]},{"emoji":"๐Ÿšฆ","aliases":["vertical_traffic_light"]},{"emoji":"๐Ÿ“ผ","aliases":["vhs"]},{"emoji":"๐Ÿ“ณ","aliases":["vibration_mode"]},{"emoji":"๐Ÿ“น","aliases":["video_camera"]},{"emoji":"๐ŸŽฎ","aliases":["video_game"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ณ","aliases":["vietnam"]},{"emoji":"๐ŸŽป","aliases":["violin"]},{"emoji":"โ™","aliases":["virgo"]},{"emoji":"๐ŸŒ‹","aliases":["volcano"]},{"emoji":"๐Ÿ","aliases":["volleyball"]},{"emoji":"๐Ÿคฎ","aliases":["vomiting_face"]},{"emoji":"๐Ÿ†š","aliases":["vs"]},{"emoji":"๐Ÿ––","aliases":["vulcan_salute"]},{"emoji":"๐Ÿง‡","aliases":["waffle"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ","aliases":["wales"]},{"emoji":"๐Ÿšถ","aliases":["walking"]},{"emoji":"๐Ÿšถโ€โ™‚๏ธ","aliases":["walking_man"]},{"emoji":"๐Ÿšถโ€โ™€๏ธ","aliases":["walking_woman"]},{"emoji":"๐Ÿ‡ผ๐Ÿ‡ซ","aliases":["wallis_futuna"]},{"emoji":"๐ŸŒ˜","aliases":["waning_crescent_moon"]},{"emoji":"๐ŸŒ–","aliases":["waning_gibbous_moon"]},{"emoji":"โš ๏ธ","aliases":["warning"]},{"emoji":"๐Ÿ—‘๏ธ","aliases":["wastebasket"]},{"emoji":"โŒš","aliases":["watch"]},{"emoji":"๐Ÿƒ","aliases":["water_buffalo"]},{"emoji":"๐Ÿคฝ","aliases":["water_polo"]},{"emoji":"๐Ÿ‰","aliases":["watermelon"]},{"emoji":"๐Ÿ‘‹","aliases":["wave"]},{"emoji":"ใ€ฐ๏ธ","aliases":["wavy_dash"]},{"emoji":"๐ŸŒ’","aliases":["waxing_crescent_moon"]},{"emoji":"๐Ÿšพ","aliases":["wc"]},{"emoji":"๐Ÿ˜ฉ","aliases":["weary"]},{"emoji":"๐Ÿ’’","aliases":["wedding"]},{"emoji":"๐Ÿ‹๏ธ","aliases":["weight_lifting"]},{"emoji":"๐Ÿ‹๏ธโ€โ™‚๏ธ","aliases":["weight_lifting_man"]},{"emoji":"๐Ÿ‹๏ธโ€โ™€๏ธ","aliases":["weight_lifting_woman"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ญ","aliases":["western_sahara"]},{"emoji":"๐Ÿณ","aliases":["whale"]},{"emoji":"๐Ÿ‹","aliases":["whale2"]},{"emoji":"โ˜ธ๏ธ","aliases":["wheel_of_dharma"]},{"emoji":"โ™ฟ","aliases":["wheelchair"]},{"emoji":"โœ…","aliases":["white_check_mark"]},{"emoji":"โšช","aliases":["white_circle"]},{"emoji":"๐Ÿณ๏ธ","aliases":["white_flag"]},{"emoji":"๐Ÿ’ฎ","aliases":["white_flower"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆณ","aliases":["white_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆณ","aliases":["white_haired_woman"]},{"emoji":"๐Ÿค","aliases":["white_heart"]},{"emoji":"โฌœ","aliases":["white_large_square"]},{"emoji":"โ—ฝ","aliases":["white_medium_small_square"]},{"emoji":"โ—ป๏ธ","aliases":["white_medium_square"]},{"emoji":"โ–ซ๏ธ","aliases":["white_small_square"]},{"emoji":"๐Ÿ”ณ","aliases":["white_square_button"]},{"emoji":"๐Ÿฅ€","aliases":["wilted_flower"]},{"emoji":"๐ŸŽ","aliases":["wind_chime"]},{"emoji":"๐ŸŒฌ๏ธ","aliases":["wind_face"]},{"emoji":"๐Ÿท","aliases":["wine_glass"]},{"emoji":"๐Ÿ˜‰","aliases":["wink"]},{"emoji":"๐Ÿบ","aliases":["wolf"]},{"emoji":"๐Ÿ‘ฉ","aliases":["woman"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽจ","aliases":["woman_artist"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿš€","aliases":["woman_astronaut"]},{"emoji":"๐Ÿคธโ€โ™€๏ธ","aliases":["woman_cartwheeling"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿณ","aliases":["woman_cook"]},{"emoji":"๐Ÿ’ƒ","aliases":["woman_dancing","dancer"]},{"emoji":"๐Ÿคฆโ€โ™€๏ธ","aliases":["woman_facepalming"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿญ","aliases":["woman_factory_worker"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŒพ","aliases":["woman_farmer"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿš’","aliases":["woman_firefighter"]},{"emoji":"๐Ÿ‘ฉโ€โš•๏ธ","aliases":["woman_health_worker"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฝ","aliases":["woman_in_manual_wheelchair"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆผ","aliases":["woman_in_motorized_wheelchair"]},{"emoji":"๐Ÿ‘ฉโ€โš–๏ธ","aliases":["woman_judge"]},{"emoji":"๐Ÿคนโ€โ™€๏ธ","aliases":["woman_juggling"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ”ง","aliases":["woman_mechanic"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ’ผ","aliases":["woman_office_worker"]},{"emoji":"๐Ÿ‘ฉโ€โœˆ๏ธ","aliases":["woman_pilot"]},{"emoji":"๐Ÿคพโ€โ™€๏ธ","aliases":["woman_playing_handball"]},{"emoji":"๐Ÿคฝโ€โ™€๏ธ","aliases":["woman_playing_water_polo"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ”ฌ","aliases":["woman_scientist"]},{"emoji":"๐Ÿคทโ€โ™€๏ธ","aliases":["woman_shrugging"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽค","aliases":["woman_singer"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽ“","aliases":["woman_student"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿซ","aliases":["woman_teacher"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ’ป","aliases":["woman_technologist"]},{"emoji":"๐Ÿง•","aliases":["woman_with_headscarf"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฏ","aliases":["woman_with_probing_cane"]},{"emoji":"๐Ÿ‘ณโ€โ™€๏ธ","aliases":["woman_with_turban"]},{"emoji":"๐Ÿ‘š","aliases":["womans_clothes"]},{"emoji":"๐Ÿ‘’","aliases":["womans_hat"]},{"emoji":"๐Ÿคผโ€โ™€๏ธ","aliases":["women_wrestling"]},{"emoji":"๐Ÿšบ","aliases":["womens"]},{"emoji":"๐Ÿฅด","aliases":["woozy_face"]},{"emoji":"๐Ÿ—บ๏ธ","aliases":["world_map"]},{"emoji":"๐Ÿ˜Ÿ","aliases":["worried"]},{"emoji":"๐Ÿ”ง","aliases":["wrench"]},{"emoji":"๐Ÿคผ","aliases":["wrestling"]},{"emoji":"โœ๏ธ","aliases":["writing_hand"]},{"emoji":"โŒ","aliases":["x"]},{"emoji":"๐Ÿงถ","aliases":["yarn"]},{"emoji":"๐Ÿฅฑ","aliases":["yawning_face"]},{"emoji":"๐ŸŸก","aliases":["yellow_circle"]},{"emoji":"๐Ÿ’›","aliases":["yellow_heart"]},{"emoji":"๐ŸŸจ","aliases":["yellow_square"]},{"emoji":"๐Ÿ‡พ๐Ÿ‡ช","aliases":["yemen"]},{"emoji":"๐Ÿ’ด","aliases":["yen"]},{"emoji":"โ˜ฏ๏ธ","aliases":["yin_yang"]},{"emoji":"๐Ÿช€","aliases":["yo_yo"]},{"emoji":"๐Ÿ˜‹","aliases":["yum"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ฒ","aliases":["zambia"]},{"emoji":"๐Ÿคช","aliases":["zany_face"]},{"emoji":"โšก","aliases":["zap"]},{"emoji":"๐Ÿฆ“","aliases":["zebra"]},{"emoji":"0๏ธโƒฃ","aliases":["zero"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ผ","aliases":["zimbabwe"]},{"emoji":"๐Ÿค","aliases":["zipper_mouth_face"]},{"emoji":"๐ŸงŸ","aliases":["zombie"]},{"emoji":"๐ŸงŸโ€โ™‚๏ธ","aliases":["zombie_man"]},{"emoji":"๐ŸงŸโ€โ™€๏ธ","aliases":["zombie_woman"]},{"emoji":"๐Ÿ’ค","aliases":["zzz"]}] \ No newline at end of file +[{"emoji":"๐Ÿ‘","aliases":["+1","thumbsup"]},{"emoji":"๐Ÿ‘Ž","aliases":["-1","thumbsdown"]},{"emoji":"๐Ÿ’ฏ","aliases":["100"]},{"emoji":"๐Ÿ”ข","aliases":["1234"]},{"emoji":"๐Ÿฅ‡","aliases":["1st_place_medal"]},{"emoji":"๐Ÿฅˆ","aliases":["2nd_place_medal"]},{"emoji":"๐Ÿฅ‰","aliases":["3rd_place_medal"]},{"emoji":"๐ŸŽฑ","aliases":["8ball"]},{"emoji":"๐Ÿ…ฐ๏ธ","aliases":["a"]},{"emoji":"๐Ÿ†Ž","aliases":["ab"]},{"emoji":"๐Ÿงฎ","aliases":["abacus"]},{"emoji":"๐Ÿ”ค","aliases":["abc"]},{"emoji":"๐Ÿ”ก","aliases":["abcd"]},{"emoji":"๐Ÿ‰‘","aliases":["accept"]},{"emoji":"๐Ÿฉน","aliases":["adhesive_bandage"]},{"emoji":"๐Ÿง‘","aliases":["adult"]},{"emoji":"๐Ÿšก","aliases":["aerial_tramway"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ซ","aliases":["afghanistan"]},{"emoji":"โœˆ๏ธ","aliases":["airplane"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฝ","aliases":["aland_islands"]},{"emoji":"โฐ","aliases":["alarm_clock"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฑ","aliases":["albania"]},{"emoji":"โš—๏ธ","aliases":["alembic"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฟ","aliases":["algeria"]},{"emoji":"๐Ÿ‘ฝ","aliases":["alien"]},{"emoji":"๐Ÿš‘","aliases":["ambulance"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ธ","aliases":["american_samoa"]},{"emoji":"๐Ÿบ","aliases":["amphora"]},{"emoji":"โš“","aliases":["anchor"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฉ","aliases":["andorra"]},{"emoji":"๐Ÿ‘ผ","aliases":["angel"]},{"emoji":"๐Ÿ’ข","aliases":["anger"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ด","aliases":["angola"]},{"emoji":"๐Ÿ˜ ","aliases":["angry"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฎ","aliases":["anguilla"]},{"emoji":"๐Ÿ˜ง","aliases":["anguished"]},{"emoji":"๐Ÿœ","aliases":["ant"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ถ","aliases":["antarctica"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฌ","aliases":["antigua_barbuda"]},{"emoji":"๐ŸŽ","aliases":["apple"]},{"emoji":"โ™’","aliases":["aquarius"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ท","aliases":["argentina"]},{"emoji":"โ™ˆ","aliases":["aries"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฒ","aliases":["armenia"]},{"emoji":"โ—€๏ธ","aliases":["arrow_backward"]},{"emoji":"โฌ","aliases":["arrow_double_down"]},{"emoji":"โซ","aliases":["arrow_double_up"]},{"emoji":"โฌ‡๏ธ","aliases":["arrow_down"]},{"emoji":"๐Ÿ”ฝ","aliases":["arrow_down_small"]},{"emoji":"โ–ถ๏ธ","aliases":["arrow_forward"]},{"emoji":"โคต๏ธ","aliases":["arrow_heading_down"]},{"emoji":"โคด๏ธ","aliases":["arrow_heading_up"]},{"emoji":"โฌ…๏ธ","aliases":["arrow_left"]},{"emoji":"โ†™๏ธ","aliases":["arrow_lower_left"]},{"emoji":"โ†˜๏ธ","aliases":["arrow_lower_right"]},{"emoji":"โžก๏ธ","aliases":["arrow_right"]},{"emoji":"โ†ช๏ธ","aliases":["arrow_right_hook"]},{"emoji":"โฌ†๏ธ","aliases":["arrow_up"]},{"emoji":"โ†•๏ธ","aliases":["arrow_up_down"]},{"emoji":"๐Ÿ”ผ","aliases":["arrow_up_small"]},{"emoji":"โ†–๏ธ","aliases":["arrow_upper_left"]},{"emoji":"โ†—๏ธ","aliases":["arrow_upper_right"]},{"emoji":"๐Ÿ”ƒ","aliases":["arrows_clockwise"]},{"emoji":"๐Ÿ”„","aliases":["arrows_counterclockwise"]},{"emoji":"๐ŸŽจ","aliases":["art"]},{"emoji":"๐Ÿš›","aliases":["articulated_lorry"]},{"emoji":"๐Ÿ›ฐ๏ธ","aliases":["artificial_satellite"]},{"emoji":"๐Ÿง‘โ€๐ŸŽจ","aliases":["artist"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ผ","aliases":["aruba"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡จ","aliases":["ascension_island"]},{"emoji":"*๏ธโƒฃ","aliases":["asterisk"]},{"emoji":"๐Ÿ˜ฒ","aliases":["astonished"]},{"emoji":"๐Ÿง‘โ€๐Ÿš€","aliases":["astronaut"]},{"emoji":"๐Ÿ‘Ÿ","aliases":["athletic_shoe"]},{"emoji":"๐Ÿง","aliases":["atm"]},{"emoji":"โš›๏ธ","aliases":["atom_symbol"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡บ","aliases":["australia"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡น","aliases":["austria"]},{"emoji":"๐Ÿ›บ","aliases":["auto_rickshaw"]},{"emoji":"๐Ÿฅ‘","aliases":["avocado"]},{"emoji":"๐Ÿช“","aliases":["axe"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ฟ","aliases":["azerbaijan"]},{"emoji":"๐Ÿ…ฑ๏ธ","aliases":["b"]},{"emoji":"๐Ÿ‘ถ","aliases":["baby"]},{"emoji":"๐Ÿผ","aliases":["baby_bottle"]},{"emoji":"๐Ÿค","aliases":["baby_chick"]},{"emoji":"๐Ÿšผ","aliases":["baby_symbol"]},{"emoji":"๐Ÿ”™","aliases":["back"]},{"emoji":"๐Ÿฅ“","aliases":["bacon"]},{"emoji":"๐Ÿฆก","aliases":["badger"]},{"emoji":"๐Ÿธ","aliases":["badminton"]},{"emoji":"๐Ÿฅฏ","aliases":["bagel"]},{"emoji":"๐Ÿ›„","aliases":["baggage_claim"]},{"emoji":"๐Ÿฅ–","aliases":["baguette_bread"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ธ","aliases":["bahamas"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ญ","aliases":["bahrain"]},{"emoji":"โš–๏ธ","aliases":["balance_scale"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฒ","aliases":["bald_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฒ","aliases":["bald_woman"]},{"emoji":"๐Ÿฉฐ","aliases":["ballet_shoes"]},{"emoji":"๐ŸŽˆ","aliases":["balloon"]},{"emoji":"๐Ÿ—ณ๏ธ","aliases":["ballot_box"]},{"emoji":"โ˜‘๏ธ","aliases":["ballot_box_with_check"]},{"emoji":"๐ŸŽ","aliases":["bamboo"]},{"emoji":"๐ŸŒ","aliases":["banana"]},{"emoji":"โ€ผ๏ธ","aliases":["bangbang"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฉ","aliases":["bangladesh"]},{"emoji":"๐Ÿช•","aliases":["banjo"]},{"emoji":"๐Ÿฆ","aliases":["bank"]},{"emoji":"๐Ÿ“Š","aliases":["bar_chart"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ง","aliases":["barbados"]},{"emoji":"๐Ÿ’ˆ","aliases":["barber"]},{"emoji":"โšพ","aliases":["baseball"]},{"emoji":"๐Ÿงบ","aliases":["basket"]},{"emoji":"๐Ÿ€","aliases":["basketball"]},{"emoji":"๐Ÿฆ‡","aliases":["bat"]},{"emoji":"๐Ÿ›€","aliases":["bath"]},{"emoji":"๐Ÿ›","aliases":["bathtub"]},{"emoji":"๐Ÿ”‹","aliases":["battery"]},{"emoji":"๐Ÿ–๏ธ","aliases":["beach_umbrella"]},{"emoji":"๐Ÿป","aliases":["bear"]},{"emoji":"๐Ÿง”","aliases":["bearded_person"]},{"emoji":"๐Ÿ›๏ธ","aliases":["bed"]},{"emoji":"๐Ÿ","aliases":["bee","honeybee"]},{"emoji":"๐Ÿบ","aliases":["beer"]},{"emoji":"๐Ÿป","aliases":["beers"]},{"emoji":"๐Ÿ”ฐ","aliases":["beginner"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡พ","aliases":["belarus"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ช","aliases":["belgium"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฟ","aliases":["belize"]},{"emoji":"๐Ÿ””","aliases":["bell"]},{"emoji":"๐Ÿ›Ž๏ธ","aliases":["bellhop_bell"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฏ","aliases":["benin"]},{"emoji":"๐Ÿฑ","aliases":["bento"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฒ","aliases":["bermuda"]},{"emoji":"๐Ÿงƒ","aliases":["beverage_box"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡น","aliases":["bhutan"]},{"emoji":"๐Ÿšด","aliases":["bicyclist"]},{"emoji":"๐Ÿšฒ","aliases":["bike"]},{"emoji":"๐Ÿšดโ€โ™‚๏ธ","aliases":["biking_man"]},{"emoji":"๐Ÿšดโ€โ™€๏ธ","aliases":["biking_woman"]},{"emoji":"๐Ÿ‘™","aliases":["bikini"]},{"emoji":"๐Ÿงข","aliases":["billed_cap"]},{"emoji":"โ˜ฃ๏ธ","aliases":["biohazard"]},{"emoji":"๐Ÿฆ","aliases":["bird"]},{"emoji":"๐ŸŽ‚","aliases":["birthday"]},{"emoji":"โšซ","aliases":["black_circle"]},{"emoji":"๐Ÿด","aliases":["black_flag"]},{"emoji":"๐Ÿ–ค","aliases":["black_heart"]},{"emoji":"๐Ÿƒ","aliases":["black_joker"]},{"emoji":"โฌ›","aliases":["black_large_square"]},{"emoji":"โ—พ","aliases":["black_medium_small_square"]},{"emoji":"โ—ผ๏ธ","aliases":["black_medium_square"]},{"emoji":"โœ’๏ธ","aliases":["black_nib"]},{"emoji":"โ–ช๏ธ","aliases":["black_small_square"]},{"emoji":"๐Ÿ”ฒ","aliases":["black_square_button"]},{"emoji":"๐Ÿ‘ฑโ€โ™‚๏ธ","aliases":["blond_haired_man"]},{"emoji":"๐Ÿ‘ฑ","aliases":["blond_haired_person"]},{"emoji":"๐Ÿ‘ฑโ€โ™€๏ธ","aliases":["blond_haired_woman","blonde_woman"]},{"emoji":"๐ŸŒผ","aliases":["blossom"]},{"emoji":"๐Ÿก","aliases":["blowfish"]},{"emoji":"๐Ÿ“˜","aliases":["blue_book"]},{"emoji":"๐Ÿš™","aliases":["blue_car"]},{"emoji":"๐Ÿ’™","aliases":["blue_heart"]},{"emoji":"๐ŸŸฆ","aliases":["blue_square"]},{"emoji":"๐Ÿ˜Š","aliases":["blush"]},{"emoji":"๐Ÿ—","aliases":["boar"]},{"emoji":"โ›ต","aliases":["boat","sailboat"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ด","aliases":["bolivia"]},{"emoji":"๐Ÿ’ฃ","aliases":["bomb"]},{"emoji":"๐Ÿฆด","aliases":["bone"]},{"emoji":"๐Ÿ“–","aliases":["book","open_book"]},{"emoji":"๐Ÿ”–","aliases":["bookmark"]},{"emoji":"๐Ÿ“‘","aliases":["bookmark_tabs"]},{"emoji":"๐Ÿ“š","aliases":["books"]},{"emoji":"๐Ÿ’ฅ","aliases":["boom","collision"]},{"emoji":"๐Ÿ‘ข","aliases":["boot"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฆ","aliases":["bosnia_herzegovina"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ผ","aliases":["botswana"]},{"emoji":"โ›น๏ธโ€โ™‚๏ธ","aliases":["bouncing_ball_man","basketball_man"]},{"emoji":"โ›น๏ธ","aliases":["bouncing_ball_person"]},{"emoji":"โ›น๏ธโ€โ™€๏ธ","aliases":["bouncing_ball_woman","basketball_woman"]},{"emoji":"๐Ÿ’","aliases":["bouquet"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ป","aliases":["bouvet_island"]},{"emoji":"๐Ÿ™‡","aliases":["bow"]},{"emoji":"๐Ÿน","aliases":["bow_and_arrow"]},{"emoji":"๐Ÿ™‡โ€โ™‚๏ธ","aliases":["bowing_man"]},{"emoji":"๐Ÿ™‡โ€โ™€๏ธ","aliases":["bowing_woman"]},{"emoji":"๐Ÿฅฃ","aliases":["bowl_with_spoon"]},{"emoji":"๐ŸŽณ","aliases":["bowling"]},{"emoji":"๐ŸฅŠ","aliases":["boxing_glove"]},{"emoji":"๐Ÿ‘ฆ","aliases":["boy"]},{"emoji":"๐Ÿง ","aliases":["brain"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ท","aliases":["brazil"]},{"emoji":"๐Ÿž","aliases":["bread"]},{"emoji":"๐Ÿคฑ","aliases":["breast_feeding"]},{"emoji":"๐Ÿงฑ","aliases":["bricks"]},{"emoji":"๐ŸŒ‰","aliases":["bridge_at_night"]},{"emoji":"๐Ÿ’ผ","aliases":["briefcase"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ด","aliases":["british_indian_ocean_territory"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฌ","aliases":["british_virgin_islands"]},{"emoji":"๐Ÿฅฆ","aliases":["broccoli"]},{"emoji":"๐Ÿ’”","aliases":["broken_heart"]},{"emoji":"๐Ÿงน","aliases":["broom"]},{"emoji":"๐ŸŸค","aliases":["brown_circle"]},{"emoji":"๐ŸคŽ","aliases":["brown_heart"]},{"emoji":"๐ŸŸซ","aliases":["brown_square"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ณ","aliases":["brunei"]},{"emoji":"๐Ÿ›","aliases":["bug"]},{"emoji":"๐Ÿ—๏ธ","aliases":["building_construction"]},{"emoji":"๐Ÿ’ก","aliases":["bulb"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฌ","aliases":["bulgaria"]},{"emoji":"๐Ÿš…","aliases":["bullettrain_front"]},{"emoji":"๐Ÿš„","aliases":["bullettrain_side"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ซ","aliases":["burkina_faso"]},{"emoji":"๐ŸŒฏ","aliases":["burrito"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฎ","aliases":["burundi"]},{"emoji":"๐ŸšŒ","aliases":["bus"]},{"emoji":"๐Ÿ•ด๏ธ","aliases":["business_suit_levitating"]},{"emoji":"๐Ÿš","aliases":["busstop"]},{"emoji":"๐Ÿ‘ค","aliases":["bust_in_silhouette"]},{"emoji":"๐Ÿ‘ฅ","aliases":["busts_in_silhouette"]},{"emoji":"๐Ÿงˆ","aliases":["butter"]},{"emoji":"๐Ÿฆ‹","aliases":["butterfly"]},{"emoji":"๐ŸŒต","aliases":["cactus"]},{"emoji":"๐Ÿฐ","aliases":["cake"]},{"emoji":"๐Ÿ“†","aliases":["calendar"]},{"emoji":"๐Ÿค™","aliases":["call_me_hand"]},{"emoji":"๐Ÿ“ฒ","aliases":["calling"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ญ","aliases":["cambodia"]},{"emoji":"๐Ÿซ","aliases":["camel"]},{"emoji":"๐Ÿ“ท","aliases":["camera"]},{"emoji":"๐Ÿ“ธ","aliases":["camera_flash"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฒ","aliases":["cameroon"]},{"emoji":"๐Ÿ•๏ธ","aliases":["camping"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฆ","aliases":["canada"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡จ","aliases":["canary_islands"]},{"emoji":"โ™‹","aliases":["cancer"]},{"emoji":"๐Ÿ•ฏ๏ธ","aliases":["candle"]},{"emoji":"๐Ÿฌ","aliases":["candy"]},{"emoji":"๐Ÿฅซ","aliases":["canned_food"]},{"emoji":"๐Ÿ›ถ","aliases":["canoe"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ป","aliases":["cape_verde"]},{"emoji":"๐Ÿ” ","aliases":["capital_abcd"]},{"emoji":"โ™‘","aliases":["capricorn"]},{"emoji":"๐Ÿš—","aliases":["car","red_car"]},{"emoji":"๐Ÿ—ƒ๏ธ","aliases":["card_file_box"]},{"emoji":"๐Ÿ“‡","aliases":["card_index"]},{"emoji":"๐Ÿ—‚๏ธ","aliases":["card_index_dividers"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ถ","aliases":["caribbean_netherlands"]},{"emoji":"๐ŸŽ ","aliases":["carousel_horse"]},{"emoji":"๐Ÿฅ•","aliases":["carrot"]},{"emoji":"๐Ÿคธ","aliases":["cartwheeling"]},{"emoji":"๐Ÿฑ","aliases":["cat"]},{"emoji":"๐Ÿˆ","aliases":["cat2"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡พ","aliases":["cayman_islands"]},{"emoji":"๐Ÿ’ฟ","aliases":["cd"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ซ","aliases":["central_african_republic"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ฆ","aliases":["ceuta_melilla"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฉ","aliases":["chad"]},{"emoji":"โ›“๏ธ","aliases":["chains"]},{"emoji":"๐Ÿช‘","aliases":["chair"]},{"emoji":"๐Ÿพ","aliases":["champagne"]},{"emoji":"๐Ÿ’น","aliases":["chart"]},{"emoji":"๐Ÿ“‰","aliases":["chart_with_downwards_trend"]},{"emoji":"๐Ÿ“ˆ","aliases":["chart_with_upwards_trend"]},{"emoji":"๐Ÿ","aliases":["checkered_flag"]},{"emoji":"๐Ÿง€","aliases":["cheese"]},{"emoji":"๐Ÿ’","aliases":["cherries"]},{"emoji":"๐ŸŒธ","aliases":["cherry_blossom"]},{"emoji":"โ™Ÿ๏ธ","aliases":["chess_pawn"]},{"emoji":"๐ŸŒฐ","aliases":["chestnut"]},{"emoji":"๐Ÿ”","aliases":["chicken"]},{"emoji":"๐Ÿง’","aliases":["child"]},{"emoji":"๐Ÿšธ","aliases":["children_crossing"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฑ","aliases":["chile"]},{"emoji":"๐Ÿฟ๏ธ","aliases":["chipmunk"]},{"emoji":"๐Ÿซ","aliases":["chocolate_bar"]},{"emoji":"๐Ÿฅข","aliases":["chopsticks"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฝ","aliases":["christmas_island"]},{"emoji":"๐ŸŽ„","aliases":["christmas_tree"]},{"emoji":"โ›ช","aliases":["church"]},{"emoji":"๐ŸŽฆ","aliases":["cinema"]},{"emoji":"๐ŸŽช","aliases":["circus_tent"]},{"emoji":"๐ŸŒ‡","aliases":["city_sunrise"]},{"emoji":"๐ŸŒ†","aliases":["city_sunset"]},{"emoji":"๐Ÿ™๏ธ","aliases":["cityscape"]},{"emoji":"๐Ÿ†‘","aliases":["cl"]},{"emoji":"๐Ÿ—œ๏ธ","aliases":["clamp"]},{"emoji":"๐Ÿ‘","aliases":["clap"]},{"emoji":"๐ŸŽฌ","aliases":["clapper"]},{"emoji":"๐Ÿ›๏ธ","aliases":["classical_building"]},{"emoji":"๐Ÿง—","aliases":["climbing"]},{"emoji":"๐Ÿง—โ€โ™‚๏ธ","aliases":["climbing_man"]},{"emoji":"๐Ÿง—โ€โ™€๏ธ","aliases":["climbing_woman"]},{"emoji":"๐Ÿฅ‚","aliases":["clinking_glasses"]},{"emoji":"๐Ÿ“‹","aliases":["clipboard"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ต","aliases":["clipperton_island"]},{"emoji":"๐Ÿ•","aliases":["clock1"]},{"emoji":"๐Ÿ•™","aliases":["clock10"]},{"emoji":"๐Ÿ•ฅ","aliases":["clock1030"]},{"emoji":"๐Ÿ•š","aliases":["clock11"]},{"emoji":"๐Ÿ•ฆ","aliases":["clock1130"]},{"emoji":"๐Ÿ•›","aliases":["clock12"]},{"emoji":"๐Ÿ•ง","aliases":["clock1230"]},{"emoji":"๐Ÿ•œ","aliases":["clock130"]},{"emoji":"๐Ÿ•‘","aliases":["clock2"]},{"emoji":"๐Ÿ•","aliases":["clock230"]},{"emoji":"๐Ÿ•’","aliases":["clock3"]},{"emoji":"๐Ÿ•ž","aliases":["clock330"]},{"emoji":"๐Ÿ•“","aliases":["clock4"]},{"emoji":"๐Ÿ•Ÿ","aliases":["clock430"]},{"emoji":"๐Ÿ•”","aliases":["clock5"]},{"emoji":"๐Ÿ• ","aliases":["clock530"]},{"emoji":"๐Ÿ••","aliases":["clock6"]},{"emoji":"๐Ÿ•ก","aliases":["clock630"]},{"emoji":"๐Ÿ•–","aliases":["clock7"]},{"emoji":"๐Ÿ•ข","aliases":["clock730"]},{"emoji":"๐Ÿ•—","aliases":["clock8"]},{"emoji":"๐Ÿ•ฃ","aliases":["clock830"]},{"emoji":"๐Ÿ•˜","aliases":["clock9"]},{"emoji":"๐Ÿ•ค","aliases":["clock930"]},{"emoji":"๐Ÿ“•","aliases":["closed_book"]},{"emoji":"๐Ÿ”","aliases":["closed_lock_with_key"]},{"emoji":"๐ŸŒ‚","aliases":["closed_umbrella"]},{"emoji":"โ˜๏ธ","aliases":["cloud"]},{"emoji":"๐ŸŒฉ๏ธ","aliases":["cloud_with_lightning"]},{"emoji":"โ›ˆ๏ธ","aliases":["cloud_with_lightning_and_rain"]},{"emoji":"๐ŸŒง๏ธ","aliases":["cloud_with_rain"]},{"emoji":"๐ŸŒจ๏ธ","aliases":["cloud_with_snow"]},{"emoji":"๐Ÿคก","aliases":["clown_face"]},{"emoji":"โ™ฃ๏ธ","aliases":["clubs"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ณ","aliases":["cn"]},{"emoji":"๐Ÿงฅ","aliases":["coat"]},{"emoji":"๐Ÿธ","aliases":["cocktail"]},{"emoji":"๐Ÿฅฅ","aliases":["coconut"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡จ","aliases":["cocos_islands"]},{"emoji":"โ˜•","aliases":["coffee"]},{"emoji":"โšฐ๏ธ","aliases":["coffin"]},{"emoji":"๐Ÿฅถ","aliases":["cold_face"]},{"emoji":"๐Ÿ˜ฐ","aliases":["cold_sweat"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ด","aliases":["colombia"]},{"emoji":"โ˜„๏ธ","aliases":["comet"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฒ","aliases":["comoros"]},{"emoji":"๐Ÿงญ","aliases":["compass"]},{"emoji":"๐Ÿ’ป","aliases":["computer"]},{"emoji":"๐Ÿ–ฑ๏ธ","aliases":["computer_mouse"]},{"emoji":"๐ŸŽŠ","aliases":["confetti_ball"]},{"emoji":"๐Ÿ˜–","aliases":["confounded"]},{"emoji":"๐Ÿ˜•","aliases":["confused"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฌ","aliases":["congo_brazzaville"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฉ","aliases":["congo_kinshasa"]},{"emoji":"ใŠ—๏ธ","aliases":["congratulations"]},{"emoji":"๐Ÿšง","aliases":["construction"]},{"emoji":"๐Ÿ‘ท","aliases":["construction_worker"]},{"emoji":"๐Ÿ‘ทโ€โ™‚๏ธ","aliases":["construction_worker_man"]},{"emoji":"๐Ÿ‘ทโ€โ™€๏ธ","aliases":["construction_worker_woman"]},{"emoji":"๐ŸŽ›๏ธ","aliases":["control_knobs"]},{"emoji":"๐Ÿช","aliases":["convenience_store"]},{"emoji":"๐Ÿง‘โ€๐Ÿณ","aliases":["cook"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฐ","aliases":["cook_islands"]},{"emoji":"๐Ÿช","aliases":["cookie"]},{"emoji":"๐Ÿ†’","aliases":["cool"]},{"emoji":"ยฉ๏ธ","aliases":["copyright"]},{"emoji":"๐ŸŒฝ","aliases":["corn"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ท","aliases":["costa_rica"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฎ","aliases":["cote_divoire"]},{"emoji":"๐Ÿ›‹๏ธ","aliases":["couch_and_lamp"]},{"emoji":"๐Ÿ‘ซ","aliases":["couple"]},{"emoji":"๐Ÿ’‘","aliases":["couple_with_heart"]},{"emoji":"๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ","aliases":["couple_with_heart_man_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ","aliases":["couple_with_heart_woman_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ","aliases":["couple_with_heart_woman_woman"]},{"emoji":"๐Ÿ’","aliases":["couplekiss"]},{"emoji":"๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ","aliases":["couplekiss_man_man"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ","aliases":["couplekiss_man_woman"]},{"emoji":"๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ","aliases":["couplekiss_woman_woman"]},{"emoji":"๐Ÿฎ","aliases":["cow"]},{"emoji":"๐Ÿ„","aliases":["cow2"]},{"emoji":"๐Ÿค ","aliases":["cowboy_hat_face"]},{"emoji":"๐Ÿฆ€","aliases":["crab"]},{"emoji":"๐Ÿ–๏ธ","aliases":["crayon"]},{"emoji":"๐Ÿ’ณ","aliases":["credit_card"]},{"emoji":"๐ŸŒ™","aliases":["crescent_moon"]},{"emoji":"๐Ÿฆ—","aliases":["cricket"]},{"emoji":"๐Ÿ","aliases":["cricket_game"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ท","aliases":["croatia"]},{"emoji":"๐ŸŠ","aliases":["crocodile"]},{"emoji":"๐Ÿฅ","aliases":["croissant"]},{"emoji":"๐Ÿคž","aliases":["crossed_fingers"]},{"emoji":"๐ŸŽŒ","aliases":["crossed_flags"]},{"emoji":"โš”๏ธ","aliases":["crossed_swords"]},{"emoji":"๐Ÿ‘‘","aliases":["crown"]},{"emoji":"๐Ÿ˜ข","aliases":["cry"]},{"emoji":"๐Ÿ˜ฟ","aliases":["crying_cat_face"]},{"emoji":"๐Ÿ”ฎ","aliases":["crystal_ball"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡บ","aliases":["cuba"]},{"emoji":"๐Ÿฅ’","aliases":["cucumber"]},{"emoji":"๐Ÿฅค","aliases":["cup_with_straw"]},{"emoji":"๐Ÿง","aliases":["cupcake"]},{"emoji":"๐Ÿ’˜","aliases":["cupid"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ผ","aliases":["curacao"]},{"emoji":"๐ŸฅŒ","aliases":["curling_stone"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฑ","aliases":["curly_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฑ","aliases":["curly_haired_woman"]},{"emoji":"โžฐ","aliases":["curly_loop"]},{"emoji":"๐Ÿ’ฑ","aliases":["currency_exchange"]},{"emoji":"๐Ÿ›","aliases":["curry"]},{"emoji":"๐Ÿคฌ","aliases":["cursing_face"]},{"emoji":"๐Ÿฎ","aliases":["custard"]},{"emoji":"๐Ÿ›ƒ","aliases":["customs"]},{"emoji":"๐Ÿฅฉ","aliases":["cut_of_meat"]},{"emoji":"๐ŸŒ€","aliases":["cyclone"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡พ","aliases":["cyprus"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ฟ","aliases":["czech_republic"]},{"emoji":"๐Ÿ—ก๏ธ","aliases":["dagger"]},{"emoji":"๐Ÿ‘ฏ","aliases":["dancers"]},{"emoji":"๐Ÿ‘ฏโ€โ™‚๏ธ","aliases":["dancing_men"]},{"emoji":"๐Ÿ‘ฏโ€โ™€๏ธ","aliases":["dancing_women"]},{"emoji":"๐Ÿก","aliases":["dango"]},{"emoji":"๐Ÿ•ถ๏ธ","aliases":["dark_sunglasses"]},{"emoji":"๐ŸŽฏ","aliases":["dart"]},{"emoji":"๐Ÿ’จ","aliases":["dash"]},{"emoji":"๐Ÿ“…","aliases":["date"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ช","aliases":["de"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["deaf_man"]},{"emoji":"๐Ÿง","aliases":["deaf_person"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["deaf_woman"]},{"emoji":"๐ŸŒณ","aliases":["deciduous_tree"]},{"emoji":"๐ŸฆŒ","aliases":["deer"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฐ","aliases":["denmark"]},{"emoji":"๐Ÿฌ","aliases":["department_store"]},{"emoji":"๐Ÿš๏ธ","aliases":["derelict_house"]},{"emoji":"๐Ÿœ๏ธ","aliases":["desert"]},{"emoji":"๐Ÿ๏ธ","aliases":["desert_island"]},{"emoji":"๐Ÿ–ฅ๏ธ","aliases":["desktop_computer"]},{"emoji":"๐Ÿ•ต๏ธ","aliases":["detective"]},{"emoji":"๐Ÿ’ ","aliases":["diamond_shape_with_a_dot_inside"]},{"emoji":"โ™ฆ๏ธ","aliases":["diamonds"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฌ","aliases":["diego_garcia"]},{"emoji":"๐Ÿ˜ž","aliases":["disappointed"]},{"emoji":"๐Ÿ˜ฅ","aliases":["disappointed_relieved"]},{"emoji":"๐Ÿคฟ","aliases":["diving_mask"]},{"emoji":"๐Ÿช”","aliases":["diya_lamp"]},{"emoji":"๐Ÿ’ซ","aliases":["dizzy"]},{"emoji":"๐Ÿ˜ต","aliases":["dizzy_face"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฏ","aliases":["djibouti"]},{"emoji":"๐Ÿงฌ","aliases":["dna"]},{"emoji":"๐Ÿšฏ","aliases":["do_not_litter"]},{"emoji":"๐Ÿถ","aliases":["dog"]},{"emoji":"๐Ÿ•","aliases":["dog2"]},{"emoji":"๐Ÿ’ต","aliases":["dollar"]},{"emoji":"๐ŸŽŽ","aliases":["dolls"]},{"emoji":"๐Ÿฌ","aliases":["dolphin","flipper"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ฒ","aliases":["dominica"]},{"emoji":"๐Ÿ‡ฉ๐Ÿ‡ด","aliases":["dominican_republic"]},{"emoji":"๐Ÿšช","aliases":["door"]},{"emoji":"๐Ÿฉ","aliases":["doughnut"]},{"emoji":"๐Ÿ•Š๏ธ","aliases":["dove"]},{"emoji":"๐Ÿ‰","aliases":["dragon"]},{"emoji":"๐Ÿฒ","aliases":["dragon_face"]},{"emoji":"๐Ÿ‘—","aliases":["dress"]},{"emoji":"๐Ÿช","aliases":["dromedary_camel"]},{"emoji":"๐Ÿคค","aliases":["drooling_face"]},{"emoji":"๐Ÿฉธ","aliases":["drop_of_blood"]},{"emoji":"๐Ÿ’ง","aliases":["droplet"]},{"emoji":"๐Ÿฅ","aliases":["drum"]},{"emoji":"๐Ÿฆ†","aliases":["duck"]},{"emoji":"๐ŸฅŸ","aliases":["dumpling"]},{"emoji":"๐Ÿ“€","aliases":["dvd"]},{"emoji":"๐Ÿฆ…","aliases":["eagle"]},{"emoji":"๐Ÿ‘‚","aliases":["ear"]},{"emoji":"๐ŸŒพ","aliases":["ear_of_rice"]},{"emoji":"๐Ÿฆป","aliases":["ear_with_hearing_aid"]},{"emoji":"๐ŸŒ","aliases":["earth_africa"]},{"emoji":"๐ŸŒŽ","aliases":["earth_americas"]},{"emoji":"๐ŸŒ","aliases":["earth_asia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡จ","aliases":["ecuador"]},{"emoji":"๐Ÿฅš","aliases":["egg"]},{"emoji":"๐Ÿ†","aliases":["eggplant"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ฌ","aliases":["egypt"]},{"emoji":"8๏ธโƒฃ","aliases":["eight"]},{"emoji":"โœด๏ธ","aliases":["eight_pointed_black_star"]},{"emoji":"โœณ๏ธ","aliases":["eight_spoked_asterisk"]},{"emoji":"โ๏ธ","aliases":["eject_button"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ป","aliases":["el_salvador"]},{"emoji":"๐Ÿ”Œ","aliases":["electric_plug"]},{"emoji":"๐Ÿ˜","aliases":["elephant"]},{"emoji":"๐Ÿง","aliases":["elf"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["elf_man"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["elf_woman"]},{"emoji":"๐Ÿ“ง","aliases":["email","e-mail"]},{"emoji":"๐Ÿ”š","aliases":["end"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ","aliases":["england"]},{"emoji":"โœ‰๏ธ","aliases":["envelope"]},{"emoji":"๐Ÿ“ฉ","aliases":["envelope_with_arrow"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ถ","aliases":["equatorial_guinea"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ท","aliases":["eritrea"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ธ","aliases":["es"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ช","aliases":["estonia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡น","aliases":["ethiopia"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡บ","aliases":["eu","european_union"]},{"emoji":"๐Ÿ’ถ","aliases":["euro"]},{"emoji":"๐Ÿฐ","aliases":["european_castle"]},{"emoji":"๐Ÿค","aliases":["european_post_office"]},{"emoji":"๐ŸŒฒ","aliases":["evergreen_tree"]},{"emoji":"โ—","aliases":["exclamation","heavy_exclamation_mark"]},{"emoji":"๐Ÿคฏ","aliases":["exploding_head"]},{"emoji":"๐Ÿ˜‘","aliases":["expressionless"]},{"emoji":"๐Ÿ‘๏ธ","aliases":["eye"]},{"emoji":"๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ","aliases":["eye_speech_bubble"]},{"emoji":"๐Ÿ‘“","aliases":["eyeglasses"]},{"emoji":"๐Ÿ‘€","aliases":["eyes"]},{"emoji":"๐Ÿค•","aliases":["face_with_head_bandage"]},{"emoji":"๐Ÿค’","aliases":["face_with_thermometer"]},{"emoji":"๐Ÿคฆ","aliases":["facepalm"]},{"emoji":"๐Ÿญ","aliases":["factory"]},{"emoji":"๐Ÿง‘โ€๐Ÿญ","aliases":["factory_worker"]},{"emoji":"๐Ÿงš","aliases":["fairy"]},{"emoji":"๐Ÿงšโ€โ™‚๏ธ","aliases":["fairy_man"]},{"emoji":"๐Ÿงšโ€โ™€๏ธ","aliases":["fairy_woman"]},{"emoji":"๐Ÿง†","aliases":["falafel"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฐ","aliases":["falkland_islands"]},{"emoji":"๐Ÿ‚","aliases":["fallen_leaf"]},{"emoji":"๐Ÿ‘ช","aliases":["family"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฆ","aliases":["family_man_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ง","aliases":["family_man_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_girl_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ","aliases":["family_man_man_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_man_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง","aliases":["family_man_man_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_man_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_man_girl_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_man_woman_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_man_woman_boy_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_man_woman_girl"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_man_woman_girl_boy"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_man_woman_girl_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_woman_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_woman_boy_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_woman_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_woman_girl_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_woman_girl_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_boy_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง","aliases":["family_woman_woman_girl"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ","aliases":["family_woman_woman_girl_boy"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง","aliases":["family_woman_woman_girl_girl"]},{"emoji":"๐Ÿง‘โ€๐ŸŒพ","aliases":["farmer"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ด","aliases":["faroe_islands"]},{"emoji":"โฉ","aliases":["fast_forward"]},{"emoji":"๐Ÿ“ ","aliases":["fax"]},{"emoji":"๐Ÿ˜จ","aliases":["fearful"]},{"emoji":"๐Ÿพ","aliases":["feet","paw_prints"]},{"emoji":"๐Ÿ•ต๏ธโ€โ™€๏ธ","aliases":["female_detective"]},{"emoji":"โ™€๏ธ","aliases":["female_sign"]},{"emoji":"๐ŸŽก","aliases":["ferris_wheel"]},{"emoji":"โ›ด๏ธ","aliases":["ferry"]},{"emoji":"๐Ÿ‘","aliases":["field_hockey"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฏ","aliases":["fiji"]},{"emoji":"๐Ÿ—„๏ธ","aliases":["file_cabinet"]},{"emoji":"๐Ÿ“","aliases":["file_folder"]},{"emoji":"๐Ÿ“ฝ๏ธ","aliases":["film_projector"]},{"emoji":"๐ŸŽž๏ธ","aliases":["film_strip"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฎ","aliases":["finland"]},{"emoji":"๐Ÿ”ฅ","aliases":["fire"]},{"emoji":"๐Ÿš’","aliases":["fire_engine"]},{"emoji":"๐Ÿงฏ","aliases":["fire_extinguisher"]},{"emoji":"๐Ÿงจ","aliases":["firecracker"]},{"emoji":"๐Ÿง‘โ€๐Ÿš’","aliases":["firefighter"]},{"emoji":"๐ŸŽ†","aliases":["fireworks"]},{"emoji":"๐ŸŒ“","aliases":["first_quarter_moon"]},{"emoji":"๐ŸŒ›","aliases":["first_quarter_moon_with_face"]},{"emoji":"๐ŸŸ","aliases":["fish"]},{"emoji":"๐Ÿฅ","aliases":["fish_cake"]},{"emoji":"๐ŸŽฃ","aliases":["fishing_pole_and_fish"]},{"emoji":"๐Ÿค›","aliases":["fist_left"]},{"emoji":"๐Ÿ‘Š","aliases":["fist_oncoming","facepunch","punch"]},{"emoji":"โœŠ","aliases":["fist_raised","fist"]},{"emoji":"๐Ÿคœ","aliases":["fist_right"]},{"emoji":"5๏ธโƒฃ","aliases":["five"]},{"emoji":"๐ŸŽ","aliases":["flags"]},{"emoji":"๐Ÿฆฉ","aliases":["flamingo"]},{"emoji":"๐Ÿ”ฆ","aliases":["flashlight"]},{"emoji":"๐Ÿฅฟ","aliases":["flat_shoe"]},{"emoji":"โšœ๏ธ","aliases":["fleur_de_lis"]},{"emoji":"๐Ÿ›ฌ","aliases":["flight_arrival"]},{"emoji":"๐Ÿ›ซ","aliases":["flight_departure"]},{"emoji":"๐Ÿ’พ","aliases":["floppy_disk"]},{"emoji":"๐ŸŽด","aliases":["flower_playing_cards"]},{"emoji":"๐Ÿ˜ณ","aliases":["flushed"]},{"emoji":"๐Ÿฅ","aliases":["flying_disc"]},{"emoji":"๐Ÿ›ธ","aliases":["flying_saucer"]},{"emoji":"๐ŸŒซ๏ธ","aliases":["fog"]},{"emoji":"๐ŸŒ","aliases":["foggy"]},{"emoji":"๐Ÿฆถ","aliases":["foot"]},{"emoji":"๐Ÿˆ","aliases":["football"]},{"emoji":"๐Ÿ‘ฃ","aliases":["footprints"]},{"emoji":"๐Ÿด","aliases":["fork_and_knife"]},{"emoji":"๐Ÿฅ ","aliases":["fortune_cookie"]},{"emoji":"โ›ฒ","aliases":["fountain"]},{"emoji":"๐Ÿ–‹๏ธ","aliases":["fountain_pen"]},{"emoji":"4๏ธโƒฃ","aliases":["four"]},{"emoji":"๐Ÿ€","aliases":["four_leaf_clover"]},{"emoji":"๐ŸฆŠ","aliases":["fox_face"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ท","aliases":["fr"]},{"emoji":"๐Ÿ–ผ๏ธ","aliases":["framed_picture"]},{"emoji":"๐Ÿ†“","aliases":["free"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ซ","aliases":["french_guiana"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ซ","aliases":["french_polynesia"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ซ","aliases":["french_southern_territories"]},{"emoji":"๐Ÿณ","aliases":["fried_egg"]},{"emoji":"๐Ÿค","aliases":["fried_shrimp"]},{"emoji":"๐ŸŸ","aliases":["fries"]},{"emoji":"๐Ÿธ","aliases":["frog"]},{"emoji":"๐Ÿ˜ฆ","aliases":["frowning"]},{"emoji":"โ˜น๏ธ","aliases":["frowning_face"]},{"emoji":"๐Ÿ™โ€โ™‚๏ธ","aliases":["frowning_man"]},{"emoji":"๐Ÿ™","aliases":["frowning_person"]},{"emoji":"๐Ÿ™โ€โ™€๏ธ","aliases":["frowning_woman"]},{"emoji":"โ›ฝ","aliases":["fuelpump"]},{"emoji":"๐ŸŒ•","aliases":["full_moon"]},{"emoji":"๐ŸŒ","aliases":["full_moon_with_face"]},{"emoji":"โšฑ๏ธ","aliases":["funeral_urn"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฆ","aliases":["gabon"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฒ","aliases":["gambia"]},{"emoji":"๐ŸŽฒ","aliases":["game_die"]},{"emoji":"๐Ÿง„","aliases":["garlic"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ง","aliases":["gb","uk"]},{"emoji":"โš™๏ธ","aliases":["gear"]},{"emoji":"๐Ÿ’Ž","aliases":["gem"]},{"emoji":"โ™Š","aliases":["gemini"]},{"emoji":"๐Ÿงž","aliases":["genie"]},{"emoji":"๐Ÿงžโ€โ™‚๏ธ","aliases":["genie_man"]},{"emoji":"๐Ÿงžโ€โ™€๏ธ","aliases":["genie_woman"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ช","aliases":["georgia"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ญ","aliases":["ghana"]},{"emoji":"๐Ÿ‘ป","aliases":["ghost"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฎ","aliases":["gibraltar"]},{"emoji":"๐ŸŽ","aliases":["gift"]},{"emoji":"๐Ÿ’","aliases":["gift_heart"]},{"emoji":"๐Ÿฆ’","aliases":["giraffe"]},{"emoji":"๐Ÿ‘ง","aliases":["girl"]},{"emoji":"๐ŸŒ","aliases":["globe_with_meridians"]},{"emoji":"๐Ÿงค","aliases":["gloves"]},{"emoji":"๐Ÿฅ…","aliases":["goal_net"]},{"emoji":"๐Ÿ","aliases":["goat"]},{"emoji":"๐Ÿฅฝ","aliases":["goggles"]},{"emoji":"โ›ณ","aliases":["golf"]},{"emoji":"๐ŸŒ๏ธ","aliases":["golfing"]},{"emoji":"๐ŸŒ๏ธโ€โ™‚๏ธ","aliases":["golfing_man"]},{"emoji":"๐ŸŒ๏ธโ€โ™€๏ธ","aliases":["golfing_woman"]},{"emoji":"๐Ÿฆ","aliases":["gorilla"]},{"emoji":"๐Ÿ‡","aliases":["grapes"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ท","aliases":["greece"]},{"emoji":"๐Ÿ","aliases":["green_apple"]},{"emoji":"๐Ÿ“—","aliases":["green_book"]},{"emoji":"๐ŸŸข","aliases":["green_circle"]},{"emoji":"๐Ÿ’š","aliases":["green_heart"]},{"emoji":"๐Ÿฅ—","aliases":["green_salad"]},{"emoji":"๐ŸŸฉ","aliases":["green_square"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฑ","aliases":["greenland"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฉ","aliases":["grenada"]},{"emoji":"โ•","aliases":["grey_exclamation"]},{"emoji":"โ”","aliases":["grey_question"]},{"emoji":"๐Ÿ˜ฌ","aliases":["grimacing"]},{"emoji":"๐Ÿ˜","aliases":["grin"]},{"emoji":"๐Ÿ˜€","aliases":["grinning"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ต","aliases":["guadeloupe"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡บ","aliases":["guam"]},{"emoji":"๐Ÿ’‚","aliases":["guard"]},{"emoji":"๐Ÿ’‚โ€โ™‚๏ธ","aliases":["guardsman"]},{"emoji":"๐Ÿ’‚โ€โ™€๏ธ","aliases":["guardswoman"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡น","aliases":["guatemala"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ฌ","aliases":["guernsey"]},{"emoji":"๐Ÿฆฎ","aliases":["guide_dog"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ณ","aliases":["guinea"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ผ","aliases":["guinea_bissau"]},{"emoji":"๐ŸŽธ","aliases":["guitar"]},{"emoji":"๐Ÿ”ซ","aliases":["gun"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡พ","aliases":["guyana"]},{"emoji":"๐Ÿ’‡","aliases":["haircut"]},{"emoji":"๐Ÿ’‡โ€โ™‚๏ธ","aliases":["haircut_man"]},{"emoji":"๐Ÿ’‡โ€โ™€๏ธ","aliases":["haircut_woman"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡น","aliases":["haiti"]},{"emoji":"๐Ÿ”","aliases":["hamburger"]},{"emoji":"๐Ÿ”จ","aliases":["hammer"]},{"emoji":"โš’๏ธ","aliases":["hammer_and_pick"]},{"emoji":"๐Ÿ› ๏ธ","aliases":["hammer_and_wrench"]},{"emoji":"๐Ÿน","aliases":["hamster"]},{"emoji":"โœ‹","aliases":["hand","raised_hand"]},{"emoji":"๐Ÿคญ","aliases":["hand_over_mouth"]},{"emoji":"๐Ÿ‘œ","aliases":["handbag"]},{"emoji":"๐Ÿคพ","aliases":["handball_person"]},{"emoji":"๐Ÿค","aliases":["handshake"]},{"emoji":"๐Ÿ’ฉ","aliases":["hankey","poop","shit"]},{"emoji":"#๏ธโƒฃ","aliases":["hash"]},{"emoji":"๐Ÿฅ","aliases":["hatched_chick"]},{"emoji":"๐Ÿฃ","aliases":["hatching_chick"]},{"emoji":"๐ŸŽง","aliases":["headphones"]},{"emoji":"๐Ÿง‘โ€โš•๏ธ","aliases":["health_worker"]},{"emoji":"๐Ÿ™‰","aliases":["hear_no_evil"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ฒ","aliases":["heard_mcdonald_islands"]},{"emoji":"โค๏ธ","aliases":["heart"]},{"emoji":"๐Ÿ’Ÿ","aliases":["heart_decoration"]},{"emoji":"๐Ÿ˜","aliases":["heart_eyes"]},{"emoji":"๐Ÿ˜ป","aliases":["heart_eyes_cat"]},{"emoji":"๐Ÿ’“","aliases":["heartbeat"]},{"emoji":"๐Ÿ’—","aliases":["heartpulse"]},{"emoji":"โ™ฅ๏ธ","aliases":["hearts"]},{"emoji":"โœ”๏ธ","aliases":["heavy_check_mark"]},{"emoji":"โž—","aliases":["heavy_division_sign"]},{"emoji":"๐Ÿ’ฒ","aliases":["heavy_dollar_sign"]},{"emoji":"โฃ๏ธ","aliases":["heavy_heart_exclamation"]},{"emoji":"โž–","aliases":["heavy_minus_sign"]},{"emoji":"โœ–๏ธ","aliases":["heavy_multiplication_x"]},{"emoji":"โž•","aliases":["heavy_plus_sign"]},{"emoji":"๐Ÿฆ”","aliases":["hedgehog"]},{"emoji":"๐Ÿš","aliases":["helicopter"]},{"emoji":"๐ŸŒฟ","aliases":["herb"]},{"emoji":"๐ŸŒบ","aliases":["hibiscus"]},{"emoji":"๐Ÿ”†","aliases":["high_brightness"]},{"emoji":"๐Ÿ‘ ","aliases":["high_heel"]},{"emoji":"๐Ÿฅพ","aliases":["hiking_boot"]},{"emoji":"๐Ÿ›•","aliases":["hindu_temple"]},{"emoji":"๐Ÿฆ›","aliases":["hippopotamus"]},{"emoji":"๐Ÿ”ช","aliases":["hocho","knife"]},{"emoji":"๐Ÿ•ณ๏ธ","aliases":["hole"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ณ","aliases":["honduras"]},{"emoji":"๐Ÿฏ","aliases":["honey_pot"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡ฐ","aliases":["hong_kong"]},{"emoji":"๐Ÿด","aliases":["horse"]},{"emoji":"๐Ÿ‡","aliases":["horse_racing"]},{"emoji":"๐Ÿฅ","aliases":["hospital"]},{"emoji":"๐Ÿฅต","aliases":["hot_face"]},{"emoji":"๐ŸŒถ๏ธ","aliases":["hot_pepper"]},{"emoji":"๐ŸŒญ","aliases":["hotdog"]},{"emoji":"๐Ÿจ","aliases":["hotel"]},{"emoji":"โ™จ๏ธ","aliases":["hotsprings"]},{"emoji":"โŒ›","aliases":["hourglass"]},{"emoji":"โณ","aliases":["hourglass_flowing_sand"]},{"emoji":"๐Ÿ ","aliases":["house"]},{"emoji":"๐Ÿก","aliases":["house_with_garden"]},{"emoji":"๐Ÿ˜๏ธ","aliases":["houses"]},{"emoji":"๐Ÿค—","aliases":["hugs"]},{"emoji":"๐Ÿ‡ญ๐Ÿ‡บ","aliases":["hungary"]},{"emoji":"๐Ÿ˜ฏ","aliases":["hushed"]},{"emoji":"๐Ÿจ","aliases":["ice_cream"]},{"emoji":"๐ŸงŠ","aliases":["ice_cube"]},{"emoji":"๐Ÿ’","aliases":["ice_hockey"]},{"emoji":"โ›ธ๏ธ","aliases":["ice_skate"]},{"emoji":"๐Ÿฆ","aliases":["icecream"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ธ","aliases":["iceland"]},{"emoji":"๐Ÿ†”","aliases":["id"]},{"emoji":"๐Ÿ‰","aliases":["ideograph_advantage"]},{"emoji":"๐Ÿ‘ฟ","aliases":["imp"]},{"emoji":"๐Ÿ“ฅ","aliases":["inbox_tray"]},{"emoji":"๐Ÿ“จ","aliases":["incoming_envelope"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ณ","aliases":["india"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฉ","aliases":["indonesia"]},{"emoji":"โ™พ๏ธ","aliases":["infinity"]},{"emoji":"โ„น๏ธ","aliases":["information_source"]},{"emoji":"๐Ÿ˜‡","aliases":["innocent"]},{"emoji":"โ‰๏ธ","aliases":["interrobang"]},{"emoji":"๐Ÿ“ฑ","aliases":["iphone"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ท","aliases":["iran"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ถ","aliases":["iraq"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ช","aliases":["ireland"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฒ","aliases":["isle_of_man"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡ฑ","aliases":["israel"]},{"emoji":"๐Ÿ‡ฎ๐Ÿ‡น","aliases":["it"]},{"emoji":"๐Ÿฎ","aliases":["izakaya_lantern","lantern"]},{"emoji":"๐ŸŽƒ","aliases":["jack_o_lantern"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ฒ","aliases":["jamaica"]},{"emoji":"๐Ÿ—พ","aliases":["japan"]},{"emoji":"๐Ÿฏ","aliases":["japanese_castle"]},{"emoji":"๐Ÿ‘บ","aliases":["japanese_goblin"]},{"emoji":"๐Ÿ‘น","aliases":["japanese_ogre"]},{"emoji":"๐Ÿ‘–","aliases":["jeans"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ช","aliases":["jersey"]},{"emoji":"๐Ÿงฉ","aliases":["jigsaw"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ด","aliases":["jordan"]},{"emoji":"๐Ÿ˜‚","aliases":["joy"]},{"emoji":"๐Ÿ˜น","aliases":["joy_cat"]},{"emoji":"๐Ÿ•น๏ธ","aliases":["joystick"]},{"emoji":"๐Ÿ‡ฏ๐Ÿ‡ต","aliases":["jp"]},{"emoji":"๐Ÿง‘โ€โš–๏ธ","aliases":["judge"]},{"emoji":"๐Ÿคน","aliases":["juggling_person"]},{"emoji":"๐Ÿ•‹","aliases":["kaaba"]},{"emoji":"๐Ÿฆ˜","aliases":["kangaroo"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฟ","aliases":["kazakhstan"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ช","aliases":["kenya"]},{"emoji":"๐Ÿ”‘","aliases":["key"]},{"emoji":"โŒจ๏ธ","aliases":["keyboard"]},{"emoji":"๐Ÿ”Ÿ","aliases":["keycap_ten"]},{"emoji":"๐Ÿ›ด","aliases":["kick_scooter"]},{"emoji":"๐Ÿ‘˜","aliases":["kimono"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฎ","aliases":["kiribati"]},{"emoji":"๐Ÿ’‹","aliases":["kiss"]},{"emoji":"๐Ÿ˜—","aliases":["kissing"]},{"emoji":"๐Ÿ˜ฝ","aliases":["kissing_cat"]},{"emoji":"๐Ÿ˜š","aliases":["kissing_closed_eyes"]},{"emoji":"๐Ÿ˜˜","aliases":["kissing_heart"]},{"emoji":"๐Ÿ˜™","aliases":["kissing_smiling_eyes"]},{"emoji":"๐Ÿช","aliases":["kite"]},{"emoji":"๐Ÿฅ","aliases":["kiwi_fruit"]},{"emoji":"๐ŸงŽโ€โ™‚๏ธ","aliases":["kneeling_man"]},{"emoji":"๐ŸงŽ","aliases":["kneeling_person"]},{"emoji":"๐ŸงŽโ€โ™€๏ธ","aliases":["kneeling_woman"]},{"emoji":"๐Ÿจ","aliases":["koala"]},{"emoji":"๐Ÿˆ","aliases":["koko"]},{"emoji":"๐Ÿ‡ฝ๐Ÿ‡ฐ","aliases":["kosovo"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ท","aliases":["kr"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ผ","aliases":["kuwait"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ฌ","aliases":["kyrgyzstan"]},{"emoji":"๐Ÿฅผ","aliases":["lab_coat"]},{"emoji":"๐Ÿท๏ธ","aliases":["label"]},{"emoji":"๐Ÿฅ","aliases":["lacrosse"]},{"emoji":"๐Ÿž","aliases":["lady_beetle"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฆ","aliases":["laos"]},{"emoji":"๐Ÿ”ต","aliases":["large_blue_circle"]},{"emoji":"๐Ÿ”ท","aliases":["large_blue_diamond"]},{"emoji":"๐Ÿ”ถ","aliases":["large_orange_diamond"]},{"emoji":"๐ŸŒ—","aliases":["last_quarter_moon"]},{"emoji":"๐ŸŒœ","aliases":["last_quarter_moon_with_face"]},{"emoji":"โœ๏ธ","aliases":["latin_cross"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ป","aliases":["latvia"]},{"emoji":"๐Ÿ˜†","aliases":["laughing","satisfied","laugh"]},{"emoji":"๐Ÿฅฌ","aliases":["leafy_green"]},{"emoji":"๐Ÿƒ","aliases":["leaves"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ง","aliases":["lebanon"]},{"emoji":"๐Ÿ“’","aliases":["ledger"]},{"emoji":"๐Ÿ›…","aliases":["left_luggage"]},{"emoji":"โ†”๏ธ","aliases":["left_right_arrow"]},{"emoji":"๐Ÿ—จ๏ธ","aliases":["left_speech_bubble"]},{"emoji":"โ†ฉ๏ธ","aliases":["leftwards_arrow_with_hook"]},{"emoji":"๐Ÿฆต","aliases":["leg"]},{"emoji":"๐Ÿ‹","aliases":["lemon"]},{"emoji":"โ™Œ","aliases":["leo"]},{"emoji":"๐Ÿ†","aliases":["leopard"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ธ","aliases":["lesotho"]},{"emoji":"๐ŸŽš๏ธ","aliases":["level_slider"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ท","aliases":["liberia"]},{"emoji":"โ™Ž","aliases":["libra"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡พ","aliases":["libya"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฎ","aliases":["liechtenstein"]},{"emoji":"๐Ÿšˆ","aliases":["light_rail"]},{"emoji":"๐Ÿ”—","aliases":["link"]},{"emoji":"๐Ÿฆ","aliases":["lion"]},{"emoji":"๐Ÿ‘„","aliases":["lips"]},{"emoji":"๐Ÿ’„","aliases":["lipstick"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡น","aliases":["lithuania"]},{"emoji":"๐ŸฆŽ","aliases":["lizard"]},{"emoji":"๐Ÿฆ™","aliases":["llama"]},{"emoji":"๐Ÿฆž","aliases":["lobster"]},{"emoji":"๐Ÿ”’","aliases":["lock"]},{"emoji":"๐Ÿ”","aliases":["lock_with_ink_pen"]},{"emoji":"๐Ÿญ","aliases":["lollipop"]},{"emoji":"โžฟ","aliases":["loop"]},{"emoji":"๐Ÿงด","aliases":["lotion_bottle"]},{"emoji":"๐Ÿง˜","aliases":["lotus_position"]},{"emoji":"๐Ÿง˜โ€โ™‚๏ธ","aliases":["lotus_position_man"]},{"emoji":"๐Ÿง˜โ€โ™€๏ธ","aliases":["lotus_position_woman"]},{"emoji":"๐Ÿ”Š","aliases":["loud_sound"]},{"emoji":"๐Ÿ“ข","aliases":["loudspeaker"]},{"emoji":"๐Ÿฉ","aliases":["love_hotel"]},{"emoji":"๐Ÿ’Œ","aliases":["love_letter"]},{"emoji":"๐ŸคŸ","aliases":["love_you_gesture"]},{"emoji":"๐Ÿ”…","aliases":["low_brightness"]},{"emoji":"๐Ÿงณ","aliases":["luggage"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡บ","aliases":["luxembourg"]},{"emoji":"๐Ÿคฅ","aliases":["lying_face"]},{"emoji":"โ“‚๏ธ","aliases":["m"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ด","aliases":["macau"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฐ","aliases":["macedonia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฌ","aliases":["madagascar"]},{"emoji":"๐Ÿ”","aliases":["mag"]},{"emoji":"๐Ÿ”Ž","aliases":["mag_right"]},{"emoji":"๐Ÿง™","aliases":["mage"]},{"emoji":"๐Ÿง™โ€โ™‚๏ธ","aliases":["mage_man"]},{"emoji":"๐Ÿง™โ€โ™€๏ธ","aliases":["mage_woman"]},{"emoji":"๐Ÿงฒ","aliases":["magnet"]},{"emoji":"๐Ÿ€„","aliases":["mahjong"]},{"emoji":"๐Ÿ“ซ","aliases":["mailbox"]},{"emoji":"๐Ÿ“ช","aliases":["mailbox_closed"]},{"emoji":"๐Ÿ“ฌ","aliases":["mailbox_with_mail"]},{"emoji":"๐Ÿ“ญ","aliases":["mailbox_with_no_mail"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ผ","aliases":["malawi"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡พ","aliases":["malaysia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ป","aliases":["maldives"]},{"emoji":"๐Ÿ•ต๏ธโ€โ™‚๏ธ","aliases":["male_detective"]},{"emoji":"โ™‚๏ธ","aliases":["male_sign"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฑ","aliases":["mali"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡น","aliases":["malta"]},{"emoji":"๐Ÿ‘จ","aliases":["man"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽจ","aliases":["man_artist"]},{"emoji":"๐Ÿ‘จโ€๐Ÿš€","aliases":["man_astronaut"]},{"emoji":"๐Ÿคธโ€โ™‚๏ธ","aliases":["man_cartwheeling"]},{"emoji":"๐Ÿ‘จโ€๐Ÿณ","aliases":["man_cook"]},{"emoji":"๐Ÿ•บ","aliases":["man_dancing"]},{"emoji":"๐Ÿคฆโ€โ™‚๏ธ","aliases":["man_facepalming"]},{"emoji":"๐Ÿ‘จโ€๐Ÿญ","aliases":["man_factory_worker"]},{"emoji":"๐Ÿ‘จโ€๐ŸŒพ","aliases":["man_farmer"]},{"emoji":"๐Ÿ‘จโ€๐Ÿš’","aliases":["man_firefighter"]},{"emoji":"๐Ÿ‘จโ€โš•๏ธ","aliases":["man_health_worker"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฝ","aliases":["man_in_manual_wheelchair"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆผ","aliases":["man_in_motorized_wheelchair"]},{"emoji":"๐Ÿ‘จโ€โš–๏ธ","aliases":["man_judge"]},{"emoji":"๐Ÿคนโ€โ™‚๏ธ","aliases":["man_juggling"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ”ง","aliases":["man_mechanic"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ’ผ","aliases":["man_office_worker"]},{"emoji":"๐Ÿ‘จโ€โœˆ๏ธ","aliases":["man_pilot"]},{"emoji":"๐Ÿคพโ€โ™‚๏ธ","aliases":["man_playing_handball"]},{"emoji":"๐Ÿคฝโ€โ™‚๏ธ","aliases":["man_playing_water_polo"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ”ฌ","aliases":["man_scientist"]},{"emoji":"๐Ÿคทโ€โ™‚๏ธ","aliases":["man_shrugging"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽค","aliases":["man_singer"]},{"emoji":"๐Ÿ‘จโ€๐ŸŽ“","aliases":["man_student"]},{"emoji":"๐Ÿ‘จโ€๐Ÿซ","aliases":["man_teacher"]},{"emoji":"๐Ÿ‘จโ€๐Ÿ’ป","aliases":["man_technologist"]},{"emoji":"๐Ÿ‘ฒ","aliases":["man_with_gua_pi_mao"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฏ","aliases":["man_with_probing_cane"]},{"emoji":"๐Ÿ‘ณโ€โ™‚๏ธ","aliases":["man_with_turban"]},{"emoji":"๐Ÿฅญ","aliases":["mango"]},{"emoji":"๐Ÿ‘ž","aliases":["mans_shoe","shoe"]},{"emoji":"๐Ÿ•ฐ๏ธ","aliases":["mantelpiece_clock"]},{"emoji":"๐Ÿฆฝ","aliases":["manual_wheelchair"]},{"emoji":"๐Ÿ","aliases":["maple_leaf"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ญ","aliases":["marshall_islands"]},{"emoji":"๐Ÿฅ‹","aliases":["martial_arts_uniform"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ถ","aliases":["martinique"]},{"emoji":"๐Ÿ˜ท","aliases":["mask"]},{"emoji":"๐Ÿ’†","aliases":["massage"]},{"emoji":"๐Ÿ’†โ€โ™‚๏ธ","aliases":["massage_man"]},{"emoji":"๐Ÿ’†โ€โ™€๏ธ","aliases":["massage_woman"]},{"emoji":"๐Ÿง‰","aliases":["mate"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ท","aliases":["mauritania"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡บ","aliases":["mauritius"]},{"emoji":"๐Ÿ‡พ๐Ÿ‡น","aliases":["mayotte"]},{"emoji":"๐Ÿ–","aliases":["meat_on_bone"]},{"emoji":"๐Ÿง‘โ€๐Ÿ”ง","aliases":["mechanic"]},{"emoji":"๐Ÿฆพ","aliases":["mechanical_arm"]},{"emoji":"๐Ÿฆฟ","aliases":["mechanical_leg"]},{"emoji":"๐ŸŽ–๏ธ","aliases":["medal_military"]},{"emoji":"๐Ÿ…","aliases":["medal_sports"]},{"emoji":"โš•๏ธ","aliases":["medical_symbol"]},{"emoji":"๐Ÿ“ฃ","aliases":["mega"]},{"emoji":"๐Ÿˆ","aliases":["melon"]},{"emoji":"๐Ÿ“","aliases":["memo","pencil"]},{"emoji":"๐Ÿคผโ€โ™‚๏ธ","aliases":["men_wrestling"]},{"emoji":"๐Ÿ•Ž","aliases":["menorah"]},{"emoji":"๐Ÿšน","aliases":["mens"]},{"emoji":"๐Ÿงœโ€โ™€๏ธ","aliases":["mermaid"]},{"emoji":"๐Ÿงœโ€โ™‚๏ธ","aliases":["merman"]},{"emoji":"๐Ÿงœ","aliases":["merperson"]},{"emoji":"๐Ÿค˜","aliases":["metal"]},{"emoji":"๐Ÿš‡","aliases":["metro"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฝ","aliases":["mexico"]},{"emoji":"๐Ÿฆ ","aliases":["microbe"]},{"emoji":"๐Ÿ‡ซ๐Ÿ‡ฒ","aliases":["micronesia"]},{"emoji":"๐ŸŽค","aliases":["microphone"]},{"emoji":"๐Ÿ”ฌ","aliases":["microscope"]},{"emoji":"๐Ÿ–•","aliases":["middle_finger","fu"]},{"emoji":"๐Ÿฅ›","aliases":["milk_glass"]},{"emoji":"๐ŸŒŒ","aliases":["milky_way"]},{"emoji":"๐Ÿš","aliases":["minibus"]},{"emoji":"๐Ÿ’ฝ","aliases":["minidisc"]},{"emoji":"๐Ÿ“ด","aliases":["mobile_phone_off"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฉ","aliases":["moldova"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡จ","aliases":["monaco"]},{"emoji":"๐Ÿค‘","aliases":["money_mouth_face"]},{"emoji":"๐Ÿ’ธ","aliases":["money_with_wings"]},{"emoji":"๐Ÿ’ฐ","aliases":["moneybag"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ณ","aliases":["mongolia"]},{"emoji":"๐Ÿ’","aliases":["monkey"]},{"emoji":"๐Ÿต","aliases":["monkey_face"]},{"emoji":"๐Ÿง","aliases":["monocle_face"]},{"emoji":"๐Ÿš","aliases":["monorail"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ช","aliases":["montenegro"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ธ","aliases":["montserrat"]},{"emoji":"๐ŸŒ”","aliases":["moon","waxing_gibbous_moon"]},{"emoji":"๐Ÿฅฎ","aliases":["moon_cake"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฆ","aliases":["morocco"]},{"emoji":"๐ŸŽ“","aliases":["mortar_board"]},{"emoji":"๐Ÿ•Œ","aliases":["mosque"]},{"emoji":"๐ŸฆŸ","aliases":["mosquito"]},{"emoji":"๐Ÿ›ฅ๏ธ","aliases":["motor_boat"]},{"emoji":"๐Ÿ›ต","aliases":["motor_scooter"]},{"emoji":"๐Ÿ๏ธ","aliases":["motorcycle"]},{"emoji":"๐Ÿฆผ","aliases":["motorized_wheelchair"]},{"emoji":"๐Ÿ›ฃ๏ธ","aliases":["motorway"]},{"emoji":"๐Ÿ—ป","aliases":["mount_fuji"]},{"emoji":"โ›ฐ๏ธ","aliases":["mountain"]},{"emoji":"๐Ÿšต","aliases":["mountain_bicyclist"]},{"emoji":"๐Ÿšตโ€โ™‚๏ธ","aliases":["mountain_biking_man"]},{"emoji":"๐Ÿšตโ€โ™€๏ธ","aliases":["mountain_biking_woman"]},{"emoji":"๐Ÿš ","aliases":["mountain_cableway"]},{"emoji":"๐Ÿšž","aliases":["mountain_railway"]},{"emoji":"๐Ÿ”๏ธ","aliases":["mountain_snow"]},{"emoji":"๐Ÿญ","aliases":["mouse"]},{"emoji":"๐Ÿ","aliases":["mouse2"]},{"emoji":"๐ŸŽฅ","aliases":["movie_camera"]},{"emoji":"๐Ÿ—ฟ","aliases":["moyai"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฟ","aliases":["mozambique"]},{"emoji":"๐Ÿคถ","aliases":["mrs_claus"]},{"emoji":"๐Ÿ’ช","aliases":["muscle"]},{"emoji":"๐Ÿ„","aliases":["mushroom"]},{"emoji":"๐ŸŽน","aliases":["musical_keyboard"]},{"emoji":"๐ŸŽต","aliases":["musical_note"]},{"emoji":"๐ŸŽผ","aliases":["musical_score"]},{"emoji":"๐Ÿ”‡","aliases":["mute"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ฒ","aliases":["myanmar"]},{"emoji":"๐Ÿ’…","aliases":["nail_care"]},{"emoji":"๐Ÿ“›","aliases":["name_badge"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฆ","aliases":["namibia"]},{"emoji":"๐Ÿž๏ธ","aliases":["national_park"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ท","aliases":["nauru"]},{"emoji":"๐Ÿคข","aliases":["nauseated_face"]},{"emoji":"๐Ÿงฟ","aliases":["nazar_amulet"]},{"emoji":"๐Ÿ‘”","aliases":["necktie"]},{"emoji":"โŽ","aliases":["negative_squared_cross_mark"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ต","aliases":["nepal"]},{"emoji":"๐Ÿค“","aliases":["nerd_face"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฑ","aliases":["netherlands"]},{"emoji":"๐Ÿ˜","aliases":["neutral_face"]},{"emoji":"๐Ÿ†•","aliases":["new"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡จ","aliases":["new_caledonia"]},{"emoji":"๐ŸŒ‘","aliases":["new_moon"]},{"emoji":"๐ŸŒš","aliases":["new_moon_with_face"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฟ","aliases":["new_zealand"]},{"emoji":"๐Ÿ“ฐ","aliases":["newspaper"]},{"emoji":"๐Ÿ—ž๏ธ","aliases":["newspaper_roll"]},{"emoji":"โญ๏ธ","aliases":["next_track_button"]},{"emoji":"๐Ÿ†–","aliases":["ng"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฎ","aliases":["nicaragua"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ช","aliases":["niger"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ฌ","aliases":["nigeria"]},{"emoji":"๐ŸŒƒ","aliases":["night_with_stars"]},{"emoji":"9๏ธโƒฃ","aliases":["nine"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡บ","aliases":["niue"]},{"emoji":"๐Ÿ”•","aliases":["no_bell"]},{"emoji":"๐Ÿšณ","aliases":["no_bicycles"]},{"emoji":"โ›”","aliases":["no_entry"]},{"emoji":"๐Ÿšซ","aliases":["no_entry_sign"]},{"emoji":"๐Ÿ™…","aliases":["no_good"]},{"emoji":"๐Ÿ™…โ€โ™‚๏ธ","aliases":["no_good_man","ng_man"]},{"emoji":"๐Ÿ™…โ€โ™€๏ธ","aliases":["no_good_woman","ng_woman"]},{"emoji":"๐Ÿ“ต","aliases":["no_mobile_phones"]},{"emoji":"๐Ÿ˜ถ","aliases":["no_mouth"]},{"emoji":"๐Ÿšท","aliases":["no_pedestrians"]},{"emoji":"๐Ÿšญ","aliases":["no_smoking"]},{"emoji":"๐Ÿšฑ","aliases":["non-potable_water"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ซ","aliases":["norfolk_island"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ต","aliases":["north_korea"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ต","aliases":["northern_mariana_islands"]},{"emoji":"๐Ÿ‡ณ๐Ÿ‡ด","aliases":["norway"]},{"emoji":"๐Ÿ‘ƒ","aliases":["nose"]},{"emoji":"๐Ÿ““","aliases":["notebook"]},{"emoji":"๐Ÿ“”","aliases":["notebook_with_decorative_cover"]},{"emoji":"๐ŸŽถ","aliases":["notes"]},{"emoji":"๐Ÿ”ฉ","aliases":["nut_and_bolt"]},{"emoji":"โญ•","aliases":["o"]},{"emoji":"๐Ÿ…พ๏ธ","aliases":["o2"]},{"emoji":"๐ŸŒŠ","aliases":["ocean"]},{"emoji":"๐Ÿ™","aliases":["octopus"]},{"emoji":"๐Ÿข","aliases":["oden"]},{"emoji":"๐Ÿข","aliases":["office"]},{"emoji":"๐Ÿง‘โ€๐Ÿ’ผ","aliases":["office_worker"]},{"emoji":"๐Ÿ›ข๏ธ","aliases":["oil_drum"]},{"emoji":"๐Ÿ†—","aliases":["ok"]},{"emoji":"๐Ÿ‘Œ","aliases":["ok_hand"]},{"emoji":"๐Ÿ™†โ€โ™‚๏ธ","aliases":["ok_man"]},{"emoji":"๐Ÿ™†","aliases":["ok_person"]},{"emoji":"๐Ÿ™†โ€โ™€๏ธ","aliases":["ok_woman"]},{"emoji":"๐Ÿ—๏ธ","aliases":["old_key"]},{"emoji":"๐Ÿง“","aliases":["older_adult"]},{"emoji":"๐Ÿ‘ด","aliases":["older_man"]},{"emoji":"๐Ÿ‘ต","aliases":["older_woman"]},{"emoji":"๐Ÿ•‰๏ธ","aliases":["om"]},{"emoji":"๐Ÿ‡ด๐Ÿ‡ฒ","aliases":["oman"]},{"emoji":"๐Ÿ”›","aliases":["on"]},{"emoji":"๐Ÿš˜","aliases":["oncoming_automobile"]},{"emoji":"๐Ÿš","aliases":["oncoming_bus"]},{"emoji":"๐Ÿš”","aliases":["oncoming_police_car"]},{"emoji":"๐Ÿš–","aliases":["oncoming_taxi"]},{"emoji":"1๏ธโƒฃ","aliases":["one"]},{"emoji":"๐Ÿฉฑ","aliases":["one_piece_swimsuit"]},{"emoji":"๐Ÿง…","aliases":["onion"]},{"emoji":"๐Ÿ“‚","aliases":["open_file_folder"]},{"emoji":"๐Ÿ‘","aliases":["open_hands"]},{"emoji":"๐Ÿ˜ฎ","aliases":["open_mouth"]},{"emoji":"โ˜‚๏ธ","aliases":["open_umbrella"]},{"emoji":"โ›Ž","aliases":["ophiuchus"]},{"emoji":"๐Ÿ“™","aliases":["orange_book"]},{"emoji":"๐ŸŸ ","aliases":["orange_circle"]},{"emoji":"๐Ÿงก","aliases":["orange_heart"]},{"emoji":"๐ŸŸง","aliases":["orange_square"]},{"emoji":"๐Ÿฆง","aliases":["orangutan"]},{"emoji":"โ˜ฆ๏ธ","aliases":["orthodox_cross"]},{"emoji":"๐Ÿฆฆ","aliases":["otter"]},{"emoji":"๐Ÿ“ค","aliases":["outbox_tray"]},{"emoji":"๐Ÿฆ‰","aliases":["owl"]},{"emoji":"๐Ÿ‚","aliases":["ox"]},{"emoji":"๐Ÿฆช","aliases":["oyster"]},{"emoji":"๐Ÿ“ฆ","aliases":["package"]},{"emoji":"๐Ÿ“„","aliases":["page_facing_up"]},{"emoji":"๐Ÿ“ƒ","aliases":["page_with_curl"]},{"emoji":"๐Ÿ“Ÿ","aliases":["pager"]},{"emoji":"๐Ÿ–Œ๏ธ","aliases":["paintbrush"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฐ","aliases":["pakistan"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ผ","aliases":["palau"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ธ","aliases":["palestinian_territories"]},{"emoji":"๐ŸŒด","aliases":["palm_tree"]},{"emoji":"๐Ÿคฒ","aliases":["palms_up_together"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฆ","aliases":["panama"]},{"emoji":"๐Ÿฅž","aliases":["pancakes"]},{"emoji":"๐Ÿผ","aliases":["panda_face"]},{"emoji":"๐Ÿ“Ž","aliases":["paperclip"]},{"emoji":"๐Ÿ–‡๏ธ","aliases":["paperclips"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฌ","aliases":["papua_new_guinea"]},{"emoji":"๐Ÿช‚","aliases":["parachute"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡พ","aliases":["paraguay"]},{"emoji":"โ›ฑ๏ธ","aliases":["parasol_on_ground"]},{"emoji":"๐Ÿ…ฟ๏ธ","aliases":["parking"]},{"emoji":"๐Ÿฆœ","aliases":["parrot"]},{"emoji":"ใ€ฝ๏ธ","aliases":["part_alternation_mark"]},{"emoji":"โ›…","aliases":["partly_sunny"]},{"emoji":"๐Ÿฅณ","aliases":["partying_face"]},{"emoji":"๐Ÿ›ณ๏ธ","aliases":["passenger_ship"]},{"emoji":"๐Ÿ›‚","aliases":["passport_control"]},{"emoji":"โธ๏ธ","aliases":["pause_button"]},{"emoji":"โ˜ฎ๏ธ","aliases":["peace_symbol"]},{"emoji":"๐Ÿ‘","aliases":["peach"]},{"emoji":"๐Ÿฆš","aliases":["peacock"]},{"emoji":"๐Ÿฅœ","aliases":["peanuts"]},{"emoji":"๐Ÿ","aliases":["pear"]},{"emoji":"๐Ÿ–Š๏ธ","aliases":["pen"]},{"emoji":"โœ๏ธ","aliases":["pencil2"]},{"emoji":"๐Ÿง","aliases":["penguin"]},{"emoji":"๐Ÿ˜”","aliases":["pensive"]},{"emoji":"๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘","aliases":["people_holding_hands"]},{"emoji":"๐ŸŽญ","aliases":["performing_arts"]},{"emoji":"๐Ÿ˜ฃ","aliases":["persevere"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฒ","aliases":["person_bald"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฑ","aliases":["person_curly_hair"]},{"emoji":"๐Ÿคบ","aliases":["person_fencing"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฝ","aliases":["person_in_manual_wheelchair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆผ","aliases":["person_in_motorized_wheelchair"]},{"emoji":"๐Ÿคต","aliases":["person_in_tuxedo"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฐ","aliases":["person_red_hair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆณ","aliases":["person_white_hair"]},{"emoji":"๐Ÿง‘โ€๐Ÿฆฏ","aliases":["person_with_probing_cane"]},{"emoji":"๐Ÿ‘ณ","aliases":["person_with_turban"]},{"emoji":"๐Ÿ‘ฐ","aliases":["person_with_veil"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ช","aliases":["peru"]},{"emoji":"๐Ÿงซ","aliases":["petri_dish"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ญ","aliases":["philippines"]},{"emoji":"โ˜Ž๏ธ","aliases":["phone","telephone"]},{"emoji":"โ›๏ธ","aliases":["pick"]},{"emoji":"๐Ÿฅง","aliases":["pie"]},{"emoji":"๐Ÿท","aliases":["pig"]},{"emoji":"๐Ÿ–","aliases":["pig2"]},{"emoji":"๐Ÿฝ","aliases":["pig_nose"]},{"emoji":"๐Ÿ’Š","aliases":["pill"]},{"emoji":"๐Ÿง‘โ€โœˆ๏ธ","aliases":["pilot"]},{"emoji":"๐Ÿค","aliases":["pinching_hand"]},{"emoji":"๐Ÿ","aliases":["pineapple"]},{"emoji":"๐Ÿ“","aliases":["ping_pong"]},{"emoji":"๐Ÿดโ€โ˜ ๏ธ","aliases":["pirate_flag"]},{"emoji":"โ™“","aliases":["pisces"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ณ","aliases":["pitcairn_islands"]},{"emoji":"๐Ÿ•","aliases":["pizza"]},{"emoji":"๐Ÿ›","aliases":["place_of_worship"]},{"emoji":"๐Ÿฝ๏ธ","aliases":["plate_with_cutlery"]},{"emoji":"โฏ๏ธ","aliases":["play_or_pause_button"]},{"emoji":"๐Ÿฅบ","aliases":["pleading_face"]},{"emoji":"๐Ÿ‘‡","aliases":["point_down"]},{"emoji":"๐Ÿ‘ˆ","aliases":["point_left"]},{"emoji":"๐Ÿ‘‰","aliases":["point_right"]},{"emoji":"โ˜๏ธ","aliases":["point_up"]},{"emoji":"๐Ÿ‘†","aliases":["point_up_2"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฑ","aliases":["poland"]},{"emoji":"๐Ÿš“","aliases":["police_car"]},{"emoji":"๐Ÿ‘ฎ","aliases":["police_officer","cop"]},{"emoji":"๐Ÿ‘ฎโ€โ™‚๏ธ","aliases":["policeman"]},{"emoji":"๐Ÿ‘ฎโ€โ™€๏ธ","aliases":["policewoman"]},{"emoji":"๐Ÿฉ","aliases":["poodle"]},{"emoji":"๐Ÿฟ","aliases":["popcorn"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡น","aliases":["portugal"]},{"emoji":"๐Ÿฃ","aliases":["post_office"]},{"emoji":"๐Ÿ“ฏ","aliases":["postal_horn"]},{"emoji":"๐Ÿ“ฎ","aliases":["postbox"]},{"emoji":"๐Ÿšฐ","aliases":["potable_water"]},{"emoji":"๐Ÿฅ”","aliases":["potato"]},{"emoji":"๐Ÿ‘","aliases":["pouch"]},{"emoji":"๐Ÿ—","aliases":["poultry_leg"]},{"emoji":"๐Ÿ’ท","aliases":["pound"]},{"emoji":"๐Ÿ˜พ","aliases":["pouting_cat"]},{"emoji":"๐Ÿ™Ž","aliases":["pouting_face"]},{"emoji":"๐Ÿ™Žโ€โ™‚๏ธ","aliases":["pouting_man"]},{"emoji":"๐Ÿ™Žโ€โ™€๏ธ","aliases":["pouting_woman"]},{"emoji":"๐Ÿ™","aliases":["pray"]},{"emoji":"๐Ÿ“ฟ","aliases":["prayer_beads"]},{"emoji":"๐Ÿคฐ","aliases":["pregnant_woman"]},{"emoji":"๐Ÿฅจ","aliases":["pretzel"]},{"emoji":"โฎ๏ธ","aliases":["previous_track_button"]},{"emoji":"๐Ÿคด","aliases":["prince"]},{"emoji":"๐Ÿ‘ธ","aliases":["princess"]},{"emoji":"๐Ÿ–จ๏ธ","aliases":["printer"]},{"emoji":"๐Ÿฆฏ","aliases":["probing_cane"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ท","aliases":["puerto_rico"]},{"emoji":"๐ŸŸฃ","aliases":["purple_circle"]},{"emoji":"๐Ÿ’œ","aliases":["purple_heart"]},{"emoji":"๐ŸŸช","aliases":["purple_square"]},{"emoji":"๐Ÿ‘›","aliases":["purse"]},{"emoji":"๐Ÿ“Œ","aliases":["pushpin"]},{"emoji":"๐Ÿšฎ","aliases":["put_litter_in_its_place"]},{"emoji":"๐Ÿ‡ถ๐Ÿ‡ฆ","aliases":["qatar"]},{"emoji":"โ“","aliases":["question"]},{"emoji":"๐Ÿฐ","aliases":["rabbit"]},{"emoji":"๐Ÿ‡","aliases":["rabbit2"]},{"emoji":"๐Ÿฆ","aliases":["raccoon"]},{"emoji":"๐ŸŽ","aliases":["racehorse"]},{"emoji":"๐ŸŽ๏ธ","aliases":["racing_car"]},{"emoji":"๐Ÿ“ป","aliases":["radio"]},{"emoji":"๐Ÿ”˜","aliases":["radio_button"]},{"emoji":"โ˜ข๏ธ","aliases":["radioactive"]},{"emoji":"๐Ÿ˜ก","aliases":["rage","pout"]},{"emoji":"๐Ÿšƒ","aliases":["railway_car"]},{"emoji":"๐Ÿ›ค๏ธ","aliases":["railway_track"]},{"emoji":"๐ŸŒˆ","aliases":["rainbow"]},{"emoji":"๐Ÿณ๏ธโ€๐ŸŒˆ","aliases":["rainbow_flag"]},{"emoji":"๐Ÿคš","aliases":["raised_back_of_hand"]},{"emoji":"๐Ÿคจ","aliases":["raised_eyebrow"]},{"emoji":"๐Ÿ–๏ธ","aliases":["raised_hand_with_fingers_splayed"]},{"emoji":"๐Ÿ™Œ","aliases":["raised_hands"]},{"emoji":"๐Ÿ™‹","aliases":["raising_hand"]},{"emoji":"๐Ÿ™‹โ€โ™‚๏ธ","aliases":["raising_hand_man"]},{"emoji":"๐Ÿ™‹โ€โ™€๏ธ","aliases":["raising_hand_woman"]},{"emoji":"๐Ÿ","aliases":["ram"]},{"emoji":"๐Ÿœ","aliases":["ramen"]},{"emoji":"๐Ÿ€","aliases":["rat"]},{"emoji":"๐Ÿช’","aliases":["razor"]},{"emoji":"๐Ÿงพ","aliases":["receipt"]},{"emoji":"โบ๏ธ","aliases":["record_button"]},{"emoji":"โ™ป๏ธ","aliases":["recycle"]},{"emoji":"๐Ÿ”ด","aliases":["red_circle"]},{"emoji":"๐Ÿงง","aliases":["red_envelope"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆฐ","aliases":["red_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฐ","aliases":["red_haired_woman"]},{"emoji":"๐ŸŸฅ","aliases":["red_square"]},{"emoji":"ยฎ๏ธ","aliases":["registered"]},{"emoji":"โ˜บ๏ธ","aliases":["relaxed"]},{"emoji":"๐Ÿ˜Œ","aliases":["relieved"]},{"emoji":"๐ŸŽ—๏ธ","aliases":["reminder_ribbon"]},{"emoji":"๐Ÿ”","aliases":["repeat"]},{"emoji":"๐Ÿ”‚","aliases":["repeat_one"]},{"emoji":"โ›‘๏ธ","aliases":["rescue_worker_helmet"]},{"emoji":"๐Ÿšป","aliases":["restroom"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ช","aliases":["reunion"]},{"emoji":"๐Ÿ’ž","aliases":["revolving_hearts"]},{"emoji":"โช","aliases":["rewind"]},{"emoji":"๐Ÿฆ","aliases":["rhinoceros"]},{"emoji":"๐ŸŽ€","aliases":["ribbon"]},{"emoji":"๐Ÿš","aliases":["rice"]},{"emoji":"๐Ÿ™","aliases":["rice_ball"]},{"emoji":"๐Ÿ˜","aliases":["rice_cracker"]},{"emoji":"๐ŸŽ‘","aliases":["rice_scene"]},{"emoji":"๐Ÿ—ฏ๏ธ","aliases":["right_anger_bubble"]},{"emoji":"๐Ÿ’","aliases":["ring"]},{"emoji":"๐Ÿช","aliases":["ringed_planet"]},{"emoji":"๐Ÿค–","aliases":["robot"]},{"emoji":"๐Ÿš€","aliases":["rocket"]},{"emoji":"๐Ÿคฃ","aliases":["rofl"]},{"emoji":"๐Ÿ™„","aliases":["roll_eyes"]},{"emoji":"๐Ÿงป","aliases":["roll_of_paper"]},{"emoji":"๐ŸŽข","aliases":["roller_coaster"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ด","aliases":["romania"]},{"emoji":"๐Ÿ“","aliases":["rooster"]},{"emoji":"๐ŸŒน","aliases":["rose"]},{"emoji":"๐Ÿต๏ธ","aliases":["rosette"]},{"emoji":"๐Ÿšจ","aliases":["rotating_light"]},{"emoji":"๐Ÿ“","aliases":["round_pushpin"]},{"emoji":"๐Ÿšฃ","aliases":["rowboat"]},{"emoji":"๐Ÿšฃโ€โ™‚๏ธ","aliases":["rowing_man"]},{"emoji":"๐Ÿšฃโ€โ™€๏ธ","aliases":["rowing_woman"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡บ","aliases":["ru"]},{"emoji":"๐Ÿ‰","aliases":["rugby_football"]},{"emoji":"๐Ÿƒ","aliases":["runner","running"]},{"emoji":"๐Ÿƒโ€โ™‚๏ธ","aliases":["running_man"]},{"emoji":"๐ŸŽฝ","aliases":["running_shirt_with_sash"]},{"emoji":"๐Ÿƒโ€โ™€๏ธ","aliases":["running_woman"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ผ","aliases":["rwanda"]},{"emoji":"๐Ÿˆ‚๏ธ","aliases":["sa"]},{"emoji":"๐Ÿงท","aliases":["safety_pin"]},{"emoji":"๐Ÿฆบ","aliases":["safety_vest"]},{"emoji":"โ™","aliases":["sagittarius"]},{"emoji":"๐Ÿถ","aliases":["sake"]},{"emoji":"๐Ÿง‚","aliases":["salt"]},{"emoji":"๐Ÿ‡ผ๐Ÿ‡ธ","aliases":["samoa"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฒ","aliases":["san_marino"]},{"emoji":"๐Ÿ‘ก","aliases":["sandal"]},{"emoji":"๐Ÿฅช","aliases":["sandwich"]},{"emoji":"๐ŸŽ…","aliases":["santa"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡น","aliases":["sao_tome_principe"]},{"emoji":"๐Ÿฅป","aliases":["sari"]},{"emoji":"๐Ÿ“ก","aliases":["satellite"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฆ","aliases":["saudi_arabia"]},{"emoji":"๐Ÿง–โ€โ™‚๏ธ","aliases":["sauna_man"]},{"emoji":"๐Ÿง–","aliases":["sauna_person"]},{"emoji":"๐Ÿง–โ€โ™€๏ธ","aliases":["sauna_woman"]},{"emoji":"๐Ÿฆ•","aliases":["sauropod"]},{"emoji":"๐ŸŽท","aliases":["saxophone"]},{"emoji":"๐Ÿงฃ","aliases":["scarf"]},{"emoji":"๐Ÿซ","aliases":["school"]},{"emoji":"๐ŸŽ’","aliases":["school_satchel"]},{"emoji":"๐Ÿง‘โ€๐Ÿ”ฌ","aliases":["scientist"]},{"emoji":"โœ‚๏ธ","aliases":["scissors"]},{"emoji":"๐Ÿฆ‚","aliases":["scorpion"]},{"emoji":"โ™","aliases":["scorpius"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ","aliases":["scotland"]},{"emoji":"๐Ÿ˜ฑ","aliases":["scream"]},{"emoji":"๐Ÿ™€","aliases":["scream_cat"]},{"emoji":"๐Ÿ“œ","aliases":["scroll"]},{"emoji":"๐Ÿ’บ","aliases":["seat"]},{"emoji":"ใŠ™๏ธ","aliases":["secret"]},{"emoji":"๐Ÿ™ˆ","aliases":["see_no_evil"]},{"emoji":"๐ŸŒฑ","aliases":["seedling"]},{"emoji":"๐Ÿคณ","aliases":["selfie"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ณ","aliases":["senegal"]},{"emoji":"๐Ÿ‡ท๐Ÿ‡ธ","aliases":["serbia"]},{"emoji":"๐Ÿ•โ€๐Ÿฆบ","aliases":["service_dog"]},{"emoji":"7๏ธโƒฃ","aliases":["seven"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡จ","aliases":["seychelles"]},{"emoji":"๐Ÿฅ˜","aliases":["shallow_pan_of_food"]},{"emoji":"โ˜˜๏ธ","aliases":["shamrock"]},{"emoji":"๐Ÿฆˆ","aliases":["shark"]},{"emoji":"๐Ÿง","aliases":["shaved_ice"]},{"emoji":"๐Ÿ‘","aliases":["sheep"]},{"emoji":"๐Ÿš","aliases":["shell"]},{"emoji":"๐Ÿ›ก๏ธ","aliases":["shield"]},{"emoji":"โ›ฉ๏ธ","aliases":["shinto_shrine"]},{"emoji":"๐Ÿšข","aliases":["ship"]},{"emoji":"๐Ÿ‘•","aliases":["shirt","tshirt"]},{"emoji":"๐Ÿ›๏ธ","aliases":["shopping"]},{"emoji":"๐Ÿ›’","aliases":["shopping_cart"]},{"emoji":"๐Ÿฉณ","aliases":["shorts"]},{"emoji":"๐Ÿšฟ","aliases":["shower"]},{"emoji":"๐Ÿฆ","aliases":["shrimp"]},{"emoji":"๐Ÿคท","aliases":["shrug"]},{"emoji":"๐Ÿคซ","aliases":["shushing_face"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฑ","aliases":["sierra_leone"]},{"emoji":"๐Ÿ“ถ","aliases":["signal_strength"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฌ","aliases":["singapore"]},{"emoji":"๐Ÿง‘โ€๐ŸŽค","aliases":["singer"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฝ","aliases":["sint_maarten"]},{"emoji":"6๏ธโƒฃ","aliases":["six"]},{"emoji":"๐Ÿ”ฏ","aliases":["six_pointed_star"]},{"emoji":"๐Ÿ›น","aliases":["skateboard"]},{"emoji":"๐ŸŽฟ","aliases":["ski"]},{"emoji":"โ›ท๏ธ","aliases":["skier"]},{"emoji":"๐Ÿ’€","aliases":["skull"]},{"emoji":"โ˜ ๏ธ","aliases":["skull_and_crossbones"]},{"emoji":"๐Ÿฆจ","aliases":["skunk"]},{"emoji":"๐Ÿ›ท","aliases":["sled"]},{"emoji":"๐Ÿ˜ด","aliases":["sleeping"]},{"emoji":"๐Ÿ›Œ","aliases":["sleeping_bed"]},{"emoji":"๐Ÿ˜ช","aliases":["sleepy"]},{"emoji":"๐Ÿ™","aliases":["slightly_frowning_face"]},{"emoji":"๐Ÿ™‚","aliases":["slightly_smiling_face"]},{"emoji":"๐ŸŽฐ","aliases":["slot_machine"]},{"emoji":"๐Ÿฆฅ","aliases":["sloth"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฐ","aliases":["slovakia"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฎ","aliases":["slovenia"]},{"emoji":"๐Ÿ›ฉ๏ธ","aliases":["small_airplane"]},{"emoji":"๐Ÿ”น","aliases":["small_blue_diamond"]},{"emoji":"๐Ÿ”ธ","aliases":["small_orange_diamond"]},{"emoji":"๐Ÿ”บ","aliases":["small_red_triangle"]},{"emoji":"๐Ÿ”ป","aliases":["small_red_triangle_down"]},{"emoji":"๐Ÿ˜„","aliases":["smile"]},{"emoji":"๐Ÿ˜ธ","aliases":["smile_cat"]},{"emoji":"๐Ÿ˜ƒ","aliases":["smiley"]},{"emoji":"๐Ÿ˜บ","aliases":["smiley_cat"]},{"emoji":"๐Ÿฅฐ","aliases":["smiling_face_with_three_hearts"]},{"emoji":"๐Ÿ˜ˆ","aliases":["smiling_imp"]},{"emoji":"๐Ÿ˜","aliases":["smirk"]},{"emoji":"๐Ÿ˜ผ","aliases":["smirk_cat"]},{"emoji":"๐Ÿšฌ","aliases":["smoking"]},{"emoji":"๐ŸŒ","aliases":["snail"]},{"emoji":"๐Ÿ","aliases":["snake"]},{"emoji":"๐Ÿคง","aliases":["sneezing_face"]},{"emoji":"๐Ÿ‚","aliases":["snowboarder"]},{"emoji":"โ„๏ธ","aliases":["snowflake"]},{"emoji":"โ›„","aliases":["snowman"]},{"emoji":"โ˜ƒ๏ธ","aliases":["snowman_with_snow"]},{"emoji":"๐Ÿงผ","aliases":["soap"]},{"emoji":"๐Ÿ˜ญ","aliases":["sob"]},{"emoji":"โšฝ","aliases":["soccer"]},{"emoji":"๐Ÿงฆ","aliases":["socks"]},{"emoji":"๐ŸฅŽ","aliases":["softball"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ง","aliases":["solomon_islands"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ด","aliases":["somalia"]},{"emoji":"๐Ÿ”œ","aliases":["soon"]},{"emoji":"๐Ÿ†˜","aliases":["sos"]},{"emoji":"๐Ÿ”‰","aliases":["sound"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ฆ","aliases":["south_africa"]},{"emoji":"๐Ÿ‡ฌ๐Ÿ‡ธ","aliases":["south_georgia_south_sandwich_islands"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ธ","aliases":["south_sudan"]},{"emoji":"๐Ÿ‘พ","aliases":["space_invader"]},{"emoji":"โ™ ๏ธ","aliases":["spades"]},{"emoji":"๐Ÿ","aliases":["spaghetti"]},{"emoji":"โ‡๏ธ","aliases":["sparkle"]},{"emoji":"๐ŸŽ‡","aliases":["sparkler"]},{"emoji":"โœจ","aliases":["sparkles"]},{"emoji":"๐Ÿ’–","aliases":["sparkling_heart"]},{"emoji":"๐Ÿ™Š","aliases":["speak_no_evil"]},{"emoji":"๐Ÿ”ˆ","aliases":["speaker"]},{"emoji":"๐Ÿ—ฃ๏ธ","aliases":["speaking_head"]},{"emoji":"๐Ÿ’ฌ","aliases":["speech_balloon"]},{"emoji":"๐Ÿšค","aliases":["speedboat"]},{"emoji":"๐Ÿ•ท๏ธ","aliases":["spider"]},{"emoji":"๐Ÿ•ธ๏ธ","aliases":["spider_web"]},{"emoji":"๐Ÿ—“๏ธ","aliases":["spiral_calendar"]},{"emoji":"๐Ÿ—’๏ธ","aliases":["spiral_notepad"]},{"emoji":"๐Ÿงฝ","aliases":["sponge"]},{"emoji":"๐Ÿฅ„","aliases":["spoon"]},{"emoji":"๐Ÿฆ‘","aliases":["squid"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡ฐ","aliases":["sri_lanka"]},{"emoji":"๐Ÿ‡ง๐Ÿ‡ฑ","aliases":["st_barthelemy"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ญ","aliases":["st_helena"]},{"emoji":"๐Ÿ‡ฐ๐Ÿ‡ณ","aliases":["st_kitts_nevis"]},{"emoji":"๐Ÿ‡ฑ๐Ÿ‡จ","aliases":["st_lucia"]},{"emoji":"๐Ÿ‡ฒ๐Ÿ‡ซ","aliases":["st_martin"]},{"emoji":"๐Ÿ‡ต๐Ÿ‡ฒ","aliases":["st_pierre_miquelon"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡จ","aliases":["st_vincent_grenadines"]},{"emoji":"๐ŸŸ๏ธ","aliases":["stadium"]},{"emoji":"๐Ÿงโ€โ™‚๏ธ","aliases":["standing_man"]},{"emoji":"๐Ÿง","aliases":["standing_person"]},{"emoji":"๐Ÿงโ€โ™€๏ธ","aliases":["standing_woman"]},{"emoji":"โญ","aliases":["star"]},{"emoji":"๐ŸŒŸ","aliases":["star2"]},{"emoji":"โ˜ช๏ธ","aliases":["star_and_crescent"]},{"emoji":"โœก๏ธ","aliases":["star_of_david"]},{"emoji":"๐Ÿคฉ","aliases":["star_struck"]},{"emoji":"๐ŸŒ ","aliases":["stars"]},{"emoji":"๐Ÿš‰","aliases":["station"]},{"emoji":"๐Ÿ—ฝ","aliases":["statue_of_liberty"]},{"emoji":"๐Ÿš‚","aliases":["steam_locomotive"]},{"emoji":"๐Ÿฉบ","aliases":["stethoscope"]},{"emoji":"๐Ÿฒ","aliases":["stew"]},{"emoji":"โน๏ธ","aliases":["stop_button"]},{"emoji":"๐Ÿ›‘","aliases":["stop_sign"]},{"emoji":"โฑ๏ธ","aliases":["stopwatch"]},{"emoji":"๐Ÿ“","aliases":["straight_ruler"]},{"emoji":"๐Ÿ“","aliases":["strawberry"]},{"emoji":"๐Ÿ˜›","aliases":["stuck_out_tongue"]},{"emoji":"๐Ÿ˜","aliases":["stuck_out_tongue_closed_eyes"]},{"emoji":"๐Ÿ˜œ","aliases":["stuck_out_tongue_winking_eye"]},{"emoji":"๐Ÿง‘โ€๐ŸŽ“","aliases":["student"]},{"emoji":"๐ŸŽ™๏ธ","aliases":["studio_microphone"]},{"emoji":"๐Ÿฅ™","aliases":["stuffed_flatbread"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฉ","aliases":["sudan"]},{"emoji":"๐ŸŒฅ๏ธ","aliases":["sun_behind_large_cloud"]},{"emoji":"๐ŸŒฆ๏ธ","aliases":["sun_behind_rain_cloud"]},{"emoji":"๐ŸŒค๏ธ","aliases":["sun_behind_small_cloud"]},{"emoji":"๐ŸŒž","aliases":["sun_with_face"]},{"emoji":"๐ŸŒป","aliases":["sunflower"]},{"emoji":"๐Ÿ˜Ž","aliases":["sunglasses"]},{"emoji":"โ˜€๏ธ","aliases":["sunny"]},{"emoji":"๐ŸŒ…","aliases":["sunrise"]},{"emoji":"๐ŸŒ„","aliases":["sunrise_over_mountains"]},{"emoji":"๐Ÿฆธ","aliases":["superhero"]},{"emoji":"๐Ÿฆธโ€โ™‚๏ธ","aliases":["superhero_man"]},{"emoji":"๐Ÿฆธโ€โ™€๏ธ","aliases":["superhero_woman"]},{"emoji":"๐Ÿฆน","aliases":["supervillain"]},{"emoji":"๐Ÿฆนโ€โ™‚๏ธ","aliases":["supervillain_man"]},{"emoji":"๐Ÿฆนโ€โ™€๏ธ","aliases":["supervillain_woman"]},{"emoji":"๐Ÿ„","aliases":["surfer"]},{"emoji":"๐Ÿ„โ€โ™‚๏ธ","aliases":["surfing_man"]},{"emoji":"๐Ÿ„โ€โ™€๏ธ","aliases":["surfing_woman"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ท","aliases":["suriname"]},{"emoji":"๐Ÿฃ","aliases":["sushi"]},{"emoji":"๐ŸšŸ","aliases":["suspension_railway"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฏ","aliases":["svalbard_jan_mayen"]},{"emoji":"๐Ÿฆข","aliases":["swan"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ฟ","aliases":["swaziland"]},{"emoji":"๐Ÿ˜“","aliases":["sweat"]},{"emoji":"๐Ÿ’ฆ","aliases":["sweat_drops"]},{"emoji":"๐Ÿ˜…","aliases":["sweat_smile"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡ช","aliases":["sweden"]},{"emoji":"๐Ÿ ","aliases":["sweet_potato"]},{"emoji":"๐Ÿฉฒ","aliases":["swim_brief"]},{"emoji":"๐ŸŠ","aliases":["swimmer"]},{"emoji":"๐ŸŠโ€โ™‚๏ธ","aliases":["swimming_man"]},{"emoji":"๐ŸŠโ€โ™€๏ธ","aliases":["swimming_woman"]},{"emoji":"๐Ÿ‡จ๐Ÿ‡ญ","aliases":["switzerland"]},{"emoji":"๐Ÿ”ฃ","aliases":["symbols"]},{"emoji":"๐Ÿ•","aliases":["synagogue"]},{"emoji":"๐Ÿ‡ธ๐Ÿ‡พ","aliases":["syria"]},{"emoji":"๐Ÿ’‰","aliases":["syringe"]},{"emoji":"๐Ÿฆ–","aliases":["t-rex"]},{"emoji":"๐ŸŒฎ","aliases":["taco"]},{"emoji":"๐ŸŽ‰","aliases":["tada","hooray"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ผ","aliases":["taiwan"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฏ","aliases":["tajikistan"]},{"emoji":"๐Ÿฅก","aliases":["takeout_box"]},{"emoji":"๐ŸŽ‹","aliases":["tanabata_tree"]},{"emoji":"๐ŸŠ","aliases":["tangerine","orange","mandarin"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฟ","aliases":["tanzania"]},{"emoji":"โ™‰","aliases":["taurus"]},{"emoji":"๐Ÿš•","aliases":["taxi"]},{"emoji":"๐Ÿต","aliases":["tea"]},{"emoji":"๐Ÿง‘โ€๐Ÿซ","aliases":["teacher"]},{"emoji":"๐Ÿง‘โ€๐Ÿ’ป","aliases":["technologist"]},{"emoji":"๐Ÿงธ","aliases":["teddy_bear"]},{"emoji":"๐Ÿ“ž","aliases":["telephone_receiver"]},{"emoji":"๐Ÿ”ญ","aliases":["telescope"]},{"emoji":"๐ŸŽพ","aliases":["tennis"]},{"emoji":"โ›บ","aliases":["tent"]},{"emoji":"๐Ÿงช","aliases":["test_tube"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ญ","aliases":["thailand"]},{"emoji":"๐ŸŒก๏ธ","aliases":["thermometer"]},{"emoji":"๐Ÿค”","aliases":["thinking"]},{"emoji":"๐Ÿ’ญ","aliases":["thought_balloon"]},{"emoji":"๐Ÿงต","aliases":["thread"]},{"emoji":"3๏ธโƒฃ","aliases":["three"]},{"emoji":"๐ŸŽซ","aliases":["ticket"]},{"emoji":"๐ŸŽŸ๏ธ","aliases":["tickets"]},{"emoji":"๐Ÿฏ","aliases":["tiger"]},{"emoji":"๐Ÿ…","aliases":["tiger2"]},{"emoji":"โฒ๏ธ","aliases":["timer_clock"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฑ","aliases":["timor_leste"]},{"emoji":"๐Ÿ’โ€โ™‚๏ธ","aliases":["tipping_hand_man","sassy_man"]},{"emoji":"๐Ÿ’","aliases":["tipping_hand_person","information_desk_person"]},{"emoji":"๐Ÿ’โ€โ™€๏ธ","aliases":["tipping_hand_woman","sassy_woman"]},{"emoji":"๐Ÿ˜ซ","aliases":["tired_face"]},{"emoji":"โ„ข๏ธ","aliases":["tm"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฌ","aliases":["togo"]},{"emoji":"๐Ÿšฝ","aliases":["toilet"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฐ","aliases":["tokelau"]},{"emoji":"๐Ÿ—ผ","aliases":["tokyo_tower"]},{"emoji":"๐Ÿ…","aliases":["tomato"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ด","aliases":["tonga"]},{"emoji":"๐Ÿ‘…","aliases":["tongue"]},{"emoji":"๐Ÿงฐ","aliases":["toolbox"]},{"emoji":"๐Ÿฆท","aliases":["tooth"]},{"emoji":"๐Ÿ”","aliases":["top"]},{"emoji":"๐ŸŽฉ","aliases":["tophat"]},{"emoji":"๐ŸŒช๏ธ","aliases":["tornado"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ท","aliases":["tr"]},{"emoji":"๐Ÿ–ฒ๏ธ","aliases":["trackball"]},{"emoji":"๐Ÿšœ","aliases":["tractor"]},{"emoji":"๐Ÿšฅ","aliases":["traffic_light"]},{"emoji":"๐Ÿš‹","aliases":["train"]},{"emoji":"๐Ÿš†","aliases":["train2"]},{"emoji":"๐ŸšŠ","aliases":["tram"]},{"emoji":"๐Ÿšฉ","aliases":["triangular_flag_on_post"]},{"emoji":"๐Ÿ“","aliases":["triangular_ruler"]},{"emoji":"๐Ÿ”ฑ","aliases":["trident"]},{"emoji":"๐Ÿ‡น๐Ÿ‡น","aliases":["trinidad_tobago"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฆ","aliases":["tristan_da_cunha"]},{"emoji":"๐Ÿ˜ค","aliases":["triumph"]},{"emoji":"๐ŸšŽ","aliases":["trolleybus"]},{"emoji":"๐Ÿ†","aliases":["trophy"]},{"emoji":"๐Ÿน","aliases":["tropical_drink"]},{"emoji":"๐Ÿ ","aliases":["tropical_fish"]},{"emoji":"๐Ÿšš","aliases":["truck"]},{"emoji":"๐ŸŽบ","aliases":["trumpet"]},{"emoji":"๐ŸŒท","aliases":["tulip"]},{"emoji":"๐Ÿฅƒ","aliases":["tumbler_glass"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ณ","aliases":["tunisia"]},{"emoji":"๐Ÿฆƒ","aliases":["turkey"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ฒ","aliases":["turkmenistan"]},{"emoji":"๐Ÿ‡น๐Ÿ‡จ","aliases":["turks_caicos_islands"]},{"emoji":"๐Ÿข","aliases":["turtle"]},{"emoji":"๐Ÿ‡น๐Ÿ‡ป","aliases":["tuvalu"]},{"emoji":"๐Ÿ“บ","aliases":["tv"]},{"emoji":"๐Ÿ”€","aliases":["twisted_rightwards_arrows"]},{"emoji":"2๏ธโƒฃ","aliases":["two"]},{"emoji":"๐Ÿ’•","aliases":["two_hearts"]},{"emoji":"๐Ÿ‘ฌ","aliases":["two_men_holding_hands"]},{"emoji":"๐Ÿ‘ญ","aliases":["two_women_holding_hands"]},{"emoji":"๐Ÿˆน","aliases":["u5272"]},{"emoji":"๐Ÿˆด","aliases":["u5408"]},{"emoji":"๐Ÿˆบ","aliases":["u55b6"]},{"emoji":"๐Ÿˆฏ","aliases":["u6307"]},{"emoji":"๐Ÿˆท๏ธ","aliases":["u6708"]},{"emoji":"๐Ÿˆถ","aliases":["u6709"]},{"emoji":"๐Ÿˆต","aliases":["u6e80"]},{"emoji":"๐Ÿˆš","aliases":["u7121"]},{"emoji":"๐Ÿˆธ","aliases":["u7533"]},{"emoji":"๐Ÿˆฒ","aliases":["u7981"]},{"emoji":"๐Ÿˆณ","aliases":["u7a7a"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฌ","aliases":["uganda"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฆ","aliases":["ukraine"]},{"emoji":"โ˜”","aliases":["umbrella"]},{"emoji":"๐Ÿ˜’","aliases":["unamused"]},{"emoji":"๐Ÿ”ž","aliases":["underage"]},{"emoji":"๐Ÿฆ„","aliases":["unicorn"]},{"emoji":"๐Ÿ‡ฆ๐Ÿ‡ช","aliases":["united_arab_emirates"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ณ","aliases":["united_nations"]},{"emoji":"๐Ÿ”“","aliases":["unlock"]},{"emoji":"๐Ÿ†™","aliases":["up"]},{"emoji":"๐Ÿ™ƒ","aliases":["upside_down_face"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡พ","aliases":["uruguay"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ธ","aliases":["us"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฒ","aliases":["us_outlying_islands"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฎ","aliases":["us_virgin_islands"]},{"emoji":"๐Ÿ‡บ๐Ÿ‡ฟ","aliases":["uzbekistan"]},{"emoji":"โœŒ๏ธ","aliases":["v"]},{"emoji":"๐Ÿง›","aliases":["vampire"]},{"emoji":"๐Ÿง›โ€โ™‚๏ธ","aliases":["vampire_man"]},{"emoji":"๐Ÿง›โ€โ™€๏ธ","aliases":["vampire_woman"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡บ","aliases":["vanuatu"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ฆ","aliases":["vatican_city"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ช","aliases":["venezuela"]},{"emoji":"๐Ÿšฆ","aliases":["vertical_traffic_light"]},{"emoji":"๐Ÿ“ผ","aliases":["vhs"]},{"emoji":"๐Ÿ“ณ","aliases":["vibration_mode"]},{"emoji":"๐Ÿ“น","aliases":["video_camera"]},{"emoji":"๐ŸŽฎ","aliases":["video_game"]},{"emoji":"๐Ÿ‡ป๐Ÿ‡ณ","aliases":["vietnam"]},{"emoji":"๐ŸŽป","aliases":["violin"]},{"emoji":"โ™","aliases":["virgo"]},{"emoji":"๐ŸŒ‹","aliases":["volcano"]},{"emoji":"๐Ÿ","aliases":["volleyball"]},{"emoji":"๐Ÿคฎ","aliases":["vomiting_face"]},{"emoji":"๐Ÿ†š","aliases":["vs"]},{"emoji":"๐Ÿ––","aliases":["vulcan_salute"]},{"emoji":"๐Ÿง‡","aliases":["waffle"]},{"emoji":"๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ","aliases":["wales"]},{"emoji":"๐Ÿšถ","aliases":["walking"]},{"emoji":"๐Ÿšถโ€โ™‚๏ธ","aliases":["walking_man"]},{"emoji":"๐Ÿšถโ€โ™€๏ธ","aliases":["walking_woman"]},{"emoji":"๐Ÿ‡ผ๐Ÿ‡ซ","aliases":["wallis_futuna"]},{"emoji":"๐ŸŒ˜","aliases":["waning_crescent_moon"]},{"emoji":"๐ŸŒ–","aliases":["waning_gibbous_moon"]},{"emoji":"โš ๏ธ","aliases":["warning"]},{"emoji":"๐Ÿ—‘๏ธ","aliases":["wastebasket"]},{"emoji":"โŒš","aliases":["watch"]},{"emoji":"๐Ÿƒ","aliases":["water_buffalo"]},{"emoji":"๐Ÿคฝ","aliases":["water_polo"]},{"emoji":"๐Ÿ‰","aliases":["watermelon"]},{"emoji":"๐Ÿ‘‹","aliases":["wave"]},{"emoji":"ใ€ฐ๏ธ","aliases":["wavy_dash"]},{"emoji":"๐ŸŒ’","aliases":["waxing_crescent_moon"]},{"emoji":"๐Ÿšพ","aliases":["wc"]},{"emoji":"๐Ÿ˜ฉ","aliases":["weary"]},{"emoji":"๐Ÿ’’","aliases":["wedding"]},{"emoji":"๐Ÿ‹๏ธ","aliases":["weight_lifting"]},{"emoji":"๐Ÿ‹๏ธโ€โ™‚๏ธ","aliases":["weight_lifting_man"]},{"emoji":"๐Ÿ‹๏ธโ€โ™€๏ธ","aliases":["weight_lifting_woman"]},{"emoji":"๐Ÿ‡ช๐Ÿ‡ญ","aliases":["western_sahara"]},{"emoji":"๐Ÿณ","aliases":["whale"]},{"emoji":"๐Ÿ‹","aliases":["whale2"]},{"emoji":"โ˜ธ๏ธ","aliases":["wheel_of_dharma"]},{"emoji":"โ™ฟ","aliases":["wheelchair"]},{"emoji":"โœ…","aliases":["white_check_mark"]},{"emoji":"โšช","aliases":["white_circle"]},{"emoji":"๐Ÿณ๏ธ","aliases":["white_flag"]},{"emoji":"๐Ÿ’ฎ","aliases":["white_flower"]},{"emoji":"๐Ÿ‘จโ€๐Ÿฆณ","aliases":["white_haired_man"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆณ","aliases":["white_haired_woman"]},{"emoji":"๐Ÿค","aliases":["white_heart"]},{"emoji":"โฌœ","aliases":["white_large_square"]},{"emoji":"โ—ฝ","aliases":["white_medium_small_square"]},{"emoji":"โ—ป๏ธ","aliases":["white_medium_square"]},{"emoji":"โ–ซ๏ธ","aliases":["white_small_square"]},{"emoji":"๐Ÿ”ณ","aliases":["white_square_button"]},{"emoji":"๐Ÿฅ€","aliases":["wilted_flower"]},{"emoji":"๐ŸŽ","aliases":["wind_chime"]},{"emoji":"๐ŸŒฌ๏ธ","aliases":["wind_face"]},{"emoji":"๐Ÿท","aliases":["wine_glass"]},{"emoji":"๐Ÿ˜‰","aliases":["wink"]},{"emoji":"๐Ÿบ","aliases":["wolf"]},{"emoji":"๐Ÿ‘ฉ","aliases":["woman"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽจ","aliases":["woman_artist"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿš€","aliases":["woman_astronaut"]},{"emoji":"๐Ÿคธโ€โ™€๏ธ","aliases":["woman_cartwheeling"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿณ","aliases":["woman_cook"]},{"emoji":"๐Ÿ’ƒ","aliases":["woman_dancing","dancer"]},{"emoji":"๐Ÿคฆโ€โ™€๏ธ","aliases":["woman_facepalming"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿญ","aliases":["woman_factory_worker"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŒพ","aliases":["woman_farmer"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿš’","aliases":["woman_firefighter"]},{"emoji":"๐Ÿ‘ฉโ€โš•๏ธ","aliases":["woman_health_worker"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฝ","aliases":["woman_in_manual_wheelchair"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆผ","aliases":["woman_in_motorized_wheelchair"]},{"emoji":"๐Ÿ‘ฉโ€โš–๏ธ","aliases":["woman_judge"]},{"emoji":"๐Ÿคนโ€โ™€๏ธ","aliases":["woman_juggling"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ”ง","aliases":["woman_mechanic"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ’ผ","aliases":["woman_office_worker"]},{"emoji":"๐Ÿ‘ฉโ€โœˆ๏ธ","aliases":["woman_pilot"]},{"emoji":"๐Ÿคพโ€โ™€๏ธ","aliases":["woman_playing_handball"]},{"emoji":"๐Ÿคฝโ€โ™€๏ธ","aliases":["woman_playing_water_polo"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ”ฌ","aliases":["woman_scientist"]},{"emoji":"๐Ÿคทโ€โ™€๏ธ","aliases":["woman_shrugging"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽค","aliases":["woman_singer"]},{"emoji":"๐Ÿ‘ฉโ€๐ŸŽ“","aliases":["woman_student"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿซ","aliases":["woman_teacher"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿ’ป","aliases":["woman_technologist"]},{"emoji":"๐Ÿง•","aliases":["woman_with_headscarf"]},{"emoji":"๐Ÿ‘ฉโ€๐Ÿฆฏ","aliases":["woman_with_probing_cane"]},{"emoji":"๐Ÿ‘ณโ€โ™€๏ธ","aliases":["woman_with_turban"]},{"emoji":"๐Ÿ‘š","aliases":["womans_clothes"]},{"emoji":"๐Ÿ‘’","aliases":["womans_hat"]},{"emoji":"๐Ÿคผโ€โ™€๏ธ","aliases":["women_wrestling"]},{"emoji":"๐Ÿšบ","aliases":["womens"]},{"emoji":"๐Ÿฅด","aliases":["woozy_face"]},{"emoji":"๐Ÿ—บ๏ธ","aliases":["world_map"]},{"emoji":"๐Ÿ˜Ÿ","aliases":["worried"]},{"emoji":"๐Ÿ”ง","aliases":["wrench"]},{"emoji":"๐Ÿคผ","aliases":["wrestling"]},{"emoji":"โœ๏ธ","aliases":["writing_hand"]},{"emoji":"โŒ","aliases":["x"]},{"emoji":"๐Ÿงถ","aliases":["yarn"]},{"emoji":"๐Ÿฅฑ","aliases":["yawning_face"]},{"emoji":"๐ŸŸก","aliases":["yellow_circle"]},{"emoji":"๐Ÿ’›","aliases":["yellow_heart"]},{"emoji":"๐ŸŸจ","aliases":["yellow_square"]},{"emoji":"๐Ÿ‡พ๐Ÿ‡ช","aliases":["yemen"]},{"emoji":"๐Ÿ’ด","aliases":["yen"]},{"emoji":"โ˜ฏ๏ธ","aliases":["yin_yang"]},{"emoji":"๐Ÿช€","aliases":["yo_yo"]},{"emoji":"๐Ÿ˜‹","aliases":["yum"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ฒ","aliases":["zambia"]},{"emoji":"๐Ÿคช","aliases":["zany_face"]},{"emoji":"โšก","aliases":["zap"]},{"emoji":"๐Ÿฆ“","aliases":["zebra"]},{"emoji":"0๏ธโƒฃ","aliases":["zero"]},{"emoji":"๐Ÿ‡ฟ๐Ÿ‡ผ","aliases":["zimbabwe"]},{"emoji":"๐Ÿค","aliases":["zipper_mouth_face"]},{"emoji":"๐ŸงŸ","aliases":["zombie"]},{"emoji":"๐ŸงŸโ€โ™‚๏ธ","aliases":["zombie_man"]},{"emoji":"๐ŸงŸโ€โ™€๏ธ","aliases":["zombie_woman"]},{"emoji":"๐Ÿ’ค","aliases":["zzz"]}] \ No newline at end of file diff --git a/assets/go-licenses.json b/assets/go-licenses.json new file mode 100644 index 000000000..8f6fba4bc --- /dev/null +++ b/assets/go-licenses.json @@ -0,0 +1,762 @@ +[ + { + "name": "cloud.google.com/go/compute/metadata", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "code.gitea.io/gitea", + "body": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) 2015 The Gogs Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "code.gitea.io/gitea/modules/lfs", + "body": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) GitHub, Inc. and LFS Test Server contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "code.gitea.io/sdk/gitea", + "body": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) 2014 The Gogs Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "codeberg.org/gusted/mcaptcha", + "body": "Copyright ยฉ 2022 William Zijl\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the โ€œSoftwareโ€), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED โ€œAS ISโ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "git.sr.ht/~mariusor/go-xsd-duration", + "body": "MIT License\n\nCopyright (c) 2019 Go xsd:duration\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "gitea.com/go-chi/binding", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "gitea.com/go-chi/cache", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "gitea.com/go-chi/captcha", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "gitea.com/go-chi/session", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "gitea.com/lunny/dingtalk_webhook", + "body": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) 2015 The Gogs Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "gitea.com/lunny/levelqueue", + "body": "Copyright (c) 2019 Lunny Xiao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/42wim/sshsig", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/Azure/go-ntlmssp", + "body": "The MIT License (MIT)\n\nCopyright (c) 2016 Microsoft\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/NYTimes/gziphandler", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright 2016-2017 The New York Times Company\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/RoaringBitmap/roaring", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright 2016 by the authors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n================================================================================\n\nPortions of runcontainer.go are from the Go standard library, which is licensed\nunder:\n\nCopyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/alecthomas/chroma", + "body": "Copyright (C) 2017 Alec Thomas\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/andybalholm/brotli", + "body": "Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/anmitsu/go-shlex", + "body": "Copyright (c) anmitsu \n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/aymerick/douceur", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Aymerick JEHANNE\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/beorn7/perks/quantile", + "body": "Copyright (C) 2013 Blake Mizerany\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/bits-and-blooms/bitset", + "body": "Copyright (c) 2014 Will Fitzgerald. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/blevesearch/bleve/v2", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/bleve_index_api", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/go-porterstemmer", + "body": "Copyright (c) 2013 Charles Iliya Krempeaux ::\nhttp://changelog.ca/\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/blevesearch/gtreap", + "body": "Copyright (C) 2012 Steve Yen\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + }, + { + "name": "github.com/blevesearch/mmap-go", + "body": "Copyright (c) 2011, Evan Shaw \nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n* Neither the name of the copyright holder nor the\nnames of its contributors may be used to endorse or promote products\nderived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n" + }, + { + "name": "github.com/blevesearch/scorch_segment_api/v2", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/segment", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/snowballstem", + "body": "Copyright (c) 2001, Dr Martin Porter\nCopyright (c) 2004,2005, Richard Boulton\nCopyright (c) 2013, Yoshiki Shibukawa\nCopyright (c) 2006,2007,2009,2010,2011,2014-2019, Olly Betts\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n3. Neither the name of the Snowball project nor the names of its contributors\nmay be used to endorse or promote products derived from this software\nwithout specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/blevesearch/upsidedown_store_api", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/vellum", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/vellum/levenshtein", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n" + }, + { + "name": "github.com/blevesearch/zapx/v11", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/zapx/v12", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/zapx/v13", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/zapx/v14", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/blevesearch/zapx/v15", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/boombuler/barcode", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Florian Sundermann\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/bradfitz/gomemcache/memcache", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/buildkite/terminal-to-html/v3", + "body": "MIT License\n\nCopyright (c) 2019 Keith Pitt, Tim Lucas, Michael Pearson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/caddyserver/certmagic", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"{}\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright {yyyy} {name of copyright owner}\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/cespare/xxhash/v2", + "body": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/chi-middleware/proxy", + "body": "Copyright (c) 2020 Lauris BH\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/cloudflare/cfssl", + "body": "Copyright (c) 2014 CloudFlare Inc.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/couchbase/go-couchbase", + "body": "Copyright (c) 2013 Couchbase, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/couchbase/gomemcached", + "body": "Copyright (c) 2013 Dustin Sallings\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/couchbase/goutils", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"{}\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright {yyyy} {name of copyright owner}\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n" + }, + { + "name": "github.com/cpuguy83/go-md2man/v2/md2man", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Brian Goff\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/denisenkom/go-mssqldb", + "body": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/dgryski/go-rendezvous", + "body": "The MIT License (MIT)\n\nCopyright (c) 2017-2020 Damian Gryski \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/djherbis/buffer", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Dustin H\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/djherbis/nio/v3", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Dustin H\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/dlclark/regexp2", + "body": "The MIT License (MIT)\n\nCopyright (c) Doug Clark\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/dsnet/compress", + "body": "Copyright ยฉ 2015, Joe Tsai and The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation and/or\nother materials provided with the distribution.\n* Neither the copyright holder nor the names of its contributors may be used to\nendorse or promote products derived from this software without specific prior\nwritten permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/duo-labs/webauthn", + "body": "Copyright (c) 2017 Duo Security, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n3. Neither the name of the copyright holder nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/dustin/go-humanize", + "body": "Copyright (c) 2005-2008 Dustin Sallings \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\n" + }, + { + "name": "github.com/editorconfig/editorconfig-core-go/v2", + "body": "MIT License\nCopyright (c) 2016 The Editorconfig Team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/ethantkoenig/rupture", + "body": "MIT License\n\nCopyright (c) 2018 Ethan Koenig\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/felixge/fgprof", + "body": "The MIT License (MIT)\nCopyright ยฉ 2020 Felix Geisendรถrfer \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the โ€œSoftwareโ€), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED โ€œAS ISโ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/fsnotify/fsnotify", + "body": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2012-2019 fsnotify Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/fxamacker/cbor/v2", + "body": "MIT License\n\nCopyright (c) 2019-present Faye Amacker\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, + { + "name": "github.com/gliderlabs/ssh", + "body": "Copyright (c) 2016 Glider Labs. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Glider Labs nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/go-ap/activitypub", + "body": "MIT License\n\nCopyright (c) 2017 Golang ActitvityPub\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/go-ap/errors", + "body": "MIT License\n\nCopyright (c) 2019 Golang ActitvityPub\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/go-ap/jsonld", + "body": "MIT License\n\nCopyright (c) 2017 Marius Orcsik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/go-asn1-ber/asn1-ber", + "body": "The MIT License (MIT)\n\nCopyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\nPortions copyright (c) 2015-2016 go-asn1-ber Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/go-chi/chi/v5", + "body": "Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google\nInc.\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/go-chi/cors", + "body": "Copyright (c) 2014 Olivier Poitrey \nCopyright (c) 2016-Present https://github.com/go-chi authors\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/go-enry/go-enry/v2", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/go-fed/httpsig", + "body": "BSD 3-Clause License\n\nCopyright (c) 2018, go-fed\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/go-ldap/ldap/v3", + "body": "The MIT License (MIT)\n\nCopyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\nPortions copyright (c) 2015-2016 go-ldap Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/go-redis/redis/v8", + "body": "Copyright (c) 2013 The github.com/go-redis/redis Authors.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/go-sql-driver/mysql", + "body": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\nmeans each individual or legal entity that creates, contributes to\nthe creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\nmeans the combination of the Contributions of others (if any) used\nby a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\nmeans Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\nmeans Source Code Form to which the initial Contributor has attached\nthe notice in Exhibit A, the Executable Form of such Source Code\nForm, and Modifications of such Source Code Form, in each case\nincluding portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\nmeans\n\n(a) that the initial Contributor has attached the notice described\nin Exhibit B to the Covered Software; or\n\n(b) that the Covered Software was made available under the terms of\nversion 1.1 or earlier of the License, but not also under the\nterms of a Secondary License.\n\n1.6. \"Executable Form\"\nmeans any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\nmeans a work that combines Covered Software with other material, in\na separate file or files, that is not Covered Software.\n\n1.8. \"License\"\nmeans this document.\n\n1.9. \"Licensable\"\nmeans having the right to grant, to the maximum extent possible,\nwhether at the time of the initial grant or subsequently, any and\nall of the rights conveyed by this License.\n\n1.10. \"Modifications\"\nmeans any of the following:\n\n(a) any file in Source Code Form that results from an addition to,\ndeletion from, or modification of the contents of Covered\nSoftware; or\n\n(b) any new file in Source Code Form that contains any Covered\nSoftware.\n\n1.11. \"Patent Claims\" of a Contributor\nmeans any patent claim(s), including without limitation, method,\nprocess, and apparatus claims, in any patent Licensable by such\nContributor that would be infringed, but for the grant of the\nLicense, by the making, using, selling, offering for sale, having\nmade, import, or transfer of either its Contributions or its\nContributor Version.\n\n1.12. \"Secondary License\"\nmeans either the GNU General Public License, Version 2.0, the GNU\nLesser General Public License, Version 2.1, the GNU Affero General\nPublic License, Version 3.0, or any later versions of those\nlicenses.\n\n1.13. \"Source Code Form\"\nmeans the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\nmeans an individual or a legal entity exercising rights under this\nLicense. For legal entities, \"You\" includes any entity that\ncontrols, is controlled by, or is under common control with You. For\npurposes of this definition, \"control\" means (a) the power, direct\nor indirect, to cause the direction or management of such entity,\nwhether by contract or otherwise, or (b) ownership of more than\nfifty percent (50%) of the outstanding shares or beneficial\nownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\nLicensable by such Contributor to use, reproduce, make available,\nmodify, display, perform, distribute, and otherwise exploit its\nContributions, either on an unmodified basis, with Modifications, or\nas part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\nfor sale, have made, import, and otherwise transfer either its\nContributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\nor\n\n(b) for infringements caused by: (i) Your and any other third party's\nmodifications of Covered Software, or (ii) the combination of its\nContributions with other software (except as part of its Contributor\nVersion); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\nits Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\nForm, as described in Section 3.1, and You must inform recipients of\nthe Executable Form how they can obtain a copy of such Source Code\nForm by reasonable means in a timely manner, at a charge no more\nthan the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\nLicense, or sublicense it under different terms, provided that the\nlicense for the Executable Form does not attempt to limit or alter\nthe recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n* *\n* 6. Disclaimer of Warranty *\n* ------------------------- *\n* *\n* Covered Software is provided under this License on an \"as is\" *\n* basis, without warranty of any kind, either expressed, implied, or *\n* statutory, including, without limitation, warranties that the *\n* Covered Software is free of defects, merchantable, fit for a *\n* particular purpose or non-infringing. The entire risk as to the *\n* quality and performance of the Covered Software is with You. *\n* Should any Covered Software prove defective in any respect, You *\n* (not any Contributor) assume the cost of any necessary servicing, *\n* repair, or correction. This disclaimer of warranty constitutes an *\n* essential part of this License. No use of any Covered Software is *\n* authorized under this License except under this disclaimer. *\n* *\n************************************************************************\n\n************************************************************************\n* *\n* 7. Limitation of Liability *\n* -------------------------- *\n* *\n* Under no circumstances and under no legal theory, whether tort *\n* (including negligence), contract, or otherwise, shall any *\n* Contributor, or anyone who distributes Covered Software as *\n* permitted above, be liable to You for any direct, indirect, *\n* special, incidental, or consequential damages of any character *\n* including, without limitation, damages for lost profits, loss of *\n* goodwill, work stoppage, computer failure or malfunction, or any *\n* and all other commercial damages or losses, even if such party *\n* shall have been informed of the possibility of such damages. This *\n* limitation of liability shall not apply to liability for death or *\n* personal injury resulting from such party's negligence to the *\n* extent applicable law prohibits such limitation. Some *\n* jurisdictions do not allow the exclusion or limitation of *\n* incidental or consequential damages, so this exclusion and *\n* limitation may not apply to You. *\n* *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\nThis Source Code Form is subject to the terms of the Mozilla Public\nLicense, v. 2.0. If a copy of the MPL was not distributed with this\nfile, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\nThis Source Code Form is \"Incompatible With Secondary Licenses\", as\ndefined by the Mozilla Public License, v. 2.0.\n" + }, + { + "name": "github.com/gobwas/glob", + "body": "The MIT License (MIT)\n\nCopyright (c) 2016 Sergey Kamardin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, + { + "name": "github.com/goccy/go-json", + "body": "MIT License\n\nCopyright (c) 2020 Masaaki Goshima\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/gogs/chardet", + "body": "Copyright (c) 2012 chardet Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nPartial of the Software is derived from ICU project. See icu-license.html for\nlicense of the derivative portions.\n" + }, + { + "name": "github.com/gogs/cron", + "body": "Copyright (C) 2012 Rob Figueiredo\nAll Rights Reserved.\n\nMIT LICENSE\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/gogs/go-gogs-client", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Go Git Service\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/golang-jwt/jwt/v4", + "body": "Copyright (c) 2012 Dave Grijalva\nCopyright (c) 2021 golang-jwt maintainers\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n" + }, + { + "name": "github.com/golang-sql/civil", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/golang-sql/sqlexp", + "body": "Copyright (c) 2017 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/golang/protobuf", + "body": "Copyright 2010 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n" + }, + { + "name": "github.com/golang/snappy", + "body": "Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/google/certificate-transparency-go", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/google/go-github/v45/github", + "body": "Copyright (c) 2013 The go-github AUTHORS. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/google/go-querystring/query", + "body": "Copyright (c) 2013 Google. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/google/pprof/profile", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/google/uuid", + "body": "Copyright (c) 2009,2014 Google Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/gorilla/css/scanner", + "body": "Copyright (c) 2013, Gorilla web toolkit\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice, this\nlist of conditions and the following disclaimer in the documentation and/or\nother materials provided with the distribution.\n\nNeither the name of the {organization} nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/gorilla/feeds", + "body": "Copyright (c) 2013-2018 The Gorilla Feeds Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/gorilla/mux", + "body": "Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/gorilla/securecookie", + "body": "Copyright (c) 2012 Rodrigo Moraes. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/gorilla/sessions", + "body": "Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/hashicorp/go-cleanhttp", + "body": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\nmeans each individual or legal entity that creates, contributes to the\ncreation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\nmeans the combination of the Contributions of others (if any) used by a\nContributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\nmeans Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\nmeans Source Code Form to which the initial Contributor has attached the\nnotice in Exhibit A, the Executable Form of such Source Code Form, and\nModifications of such Source Code Form, in each case including portions\nthereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\nmeans\n\na. that the initial Contributor has attached the notice described in\nExhibit B to the Covered Software; or\n\nb. that the Covered Software was made available under the terms of\nversion 1.1 or earlier of the License, but not also under the terms of\na Secondary License.\n\n1.6. \"Executable Form\"\n\nmeans any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\nmeans a work that combines Covered Software with other material, in a\nseparate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\nmeans this document.\n\n1.9. \"Licensable\"\n\nmeans having the right to grant, to the maximum extent possible, whether\nat the time of the initial grant or subsequently, any and all of the\nrights conveyed by this License.\n\n1.10. \"Modifications\"\n\nmeans any of the following:\n\na. any file in Source Code Form that results from an addition to,\ndeletion from, or modification of the contents of Covered Software; or\n\nb. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\nmeans any patent claim(s), including without limitation, method,\nprocess, and apparatus claims, in any patent Licensable by such\nContributor that would be infringed, but for the grant of the License,\nby the making, using, selling, offering for sale, having made, import,\nor transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\nmeans either the GNU General Public License, Version 2.0, the GNU Lesser\nGeneral Public License, Version 2.1, the GNU Affero General Public\nLicense, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\nmeans the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\nmeans an individual or a legal entity exercising rights under this\nLicense. For legal entities, \"You\" includes any entity that controls, is\ncontrolled by, or is under common control with You. For purposes of this\ndefinition, \"control\" means (a) the power, direct or indirect, to cause\nthe direction or management of such entity, whether by contract or\notherwise, or (b) ownership of more than fifty percent (50%) of the\noutstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\na. under intellectual property rights (other than patent or trademark)\nLicensable by such Contributor to use, reproduce, make available,\nmodify, display, perform, distribute, and otherwise exploit its\nContributions, either on an unmodified basis, with Modifications, or\nas part of a Larger Work; and\n\nb. under Patent Claims of such Contributor to make, use, sell, offer for\nsale, have made, import, and otherwise transfer either its\nContributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\na. for any code that a Contributor has removed from Covered Software; or\n\nb. for infringements caused by: (i) Your and any other third party's\nmodifications of Covered Software, or (ii) the combination of its\nContributions with other software (except as part of its Contributor\nVersion); or\n\nc. under Patent Claims infringed by Covered Software in the absence of\nits Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights to\ngrant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in\nSection 2.1.\n\n\n3. Responsibilities\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\na. such Covered Software must also be made available in Source Code Form,\nas described in Section 3.1, and You must inform recipients of the\nExecutable Form how they can obtain a copy of such Source Code Form by\nreasonable means in a timely manner, at a charge no more than the cost\nof distribution to the recipient; and\n\nb. You may distribute such Executable Form under the terms of this\nLicense, or sublicense it under different terms, provided that the\nlicense for the Executable Form does not attempt to limit or alter the\nrecipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty, or\nlimitations of liability) contained within the Source Code Form of the\nCovered Software, except that You may alter any license notices to the\nextent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n\nIf it is impossible for You to comply with any of the terms of this License\nwith respect to some or all of the Covered Software due to statute,\njudicial order, or regulation then You must: (a) comply with the terms of\nthis License to the maximum extent possible; and (b) describe the\nlimitations and the code they affect. Such description must be placed in a\ntext file included with all distributions of the Covered Software under\nthis License. Except to the extent prohibited by statute or regulation,\nsuch description must be sufficiently detailed for a recipient of ordinary\nskill to be able to understand it.\n\n5. Termination\n\n5.1. The rights granted under this License will terminate automatically if You\nfail to comply with any of its terms. However, if You become compliant,\nthen the rights granted under this License from a particular Contributor\nare reinstated (a) provisionally, unless and until such Contributor\nexplicitly and finally terminates Your grants, and (b) on an ongoing\nbasis, if such Contributor fails to notify You of the non-compliance by\nsome reasonable means prior to 60 days after You have come back into\ncompliance. Moreover, Your grants from a particular Contributor are\nreinstated on an ongoing basis if such Contributor notifies You of the\nnon-compliance by some reasonable means, this is the first time You have\nreceived notice of non-compliance with this License from such\nContributor, and You become compliant prior to 30 days after Your receipt\nof the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user\nlicense agreements (excluding distributors and resellers) which have been\nvalidly granted by You or Your distributors under this License prior to\ntermination shall survive termination.\n\n6. Disclaimer of Warranty\n\nCovered Software is provided under this License on an \"as is\" basis,\nwithout warranty of any kind, either expressed, implied, or statutory,\nincluding, without limitation, warranties that the Covered Software is free\nof defects, merchantable, fit for a particular purpose or non-infringing.\nThe entire risk as to the quality and performance of the Covered Software\nis with You. Should any Covered Software prove defective in any respect,\nYou (not any Contributor) assume the cost of any necessary servicing,\nrepair, or correction. This disclaimer of warranty constitutes an essential\npart of this License. No use of any Covered Software is authorized under\nthis License except under this disclaimer.\n\n7. Limitation of Liability\n\nUnder no circumstances and under no legal theory, whether tort (including\nnegligence), contract, or otherwise, shall any Contributor, or anyone who\ndistributes Covered Software as permitted above, be liable to You for any\ndirect, indirect, special, incidental, or consequential damages of any\ncharacter including, without limitation, damages for lost profits, loss of\ngoodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses, even if such party shall have been\ninformed of the possibility of such damages. This limitation of liability\nshall not apply to liability for death or personal injury resulting from\nsuch party's negligence to the extent applicable law prohibits such\nlimitation. Some jurisdictions do not allow the exclusion or limitation of\nincidental or consequential damages, so this exclusion and limitation may\nnot apply to You.\n\n8. Litigation\n\nAny litigation relating to this License may be brought only in the courts\nof a jurisdiction where the defendant maintains its principal place of\nbusiness and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions. Nothing\nin this Section shall prevent a party's ability to bring cross-claims or\ncounter-claims.\n\n9. Miscellaneous\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides that\nthe language of a contract shall be construed against the drafter shall not\nbe used to construe this License against a Contributor.\n\n\n10. Versions of the License\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses If You choose to distribute Source Code Form that is\nIncompatible With Secondary Licenses under the terms of this version of\nthe License, the notice described in Exhibit B of this License must be\nattached.\n\nExhibit A - Source Code Form License Notice\n\nThis Source Code Form is subject to the\nterms of the Mozilla Public License, v.\n2.0. If a copy of the MPL was not\ndistributed with this file, You can\nobtain one at\nhttp://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular file,\nthen You may include the notice in a location (such as a LICENSE file in a\nrelevant directory) where a recipient would be likely to look for such a\nnotice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n\nThis Source Code Form is \"Incompatible\nWith Secondary Licenses\", as defined by\nthe Mozilla Public License, v. 2.0.\n\n" + }, + { + "name": "github.com/hashicorp/go-retryablehttp", + "body": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\nmeans each individual or legal entity that creates, contributes to the\ncreation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\nmeans the combination of the Contributions of others (if any) used by a\nContributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\nmeans Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\nmeans Source Code Form to which the initial Contributor has attached the\nnotice in Exhibit A, the Executable Form of such Source Code Form, and\nModifications of such Source Code Form, in each case including portions\nthereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\nmeans\n\na. that the initial Contributor has attached the notice described in\nExhibit B to the Covered Software; or\n\nb. that the Covered Software was made available under the terms of\nversion 1.1 or earlier of the License, but not also under the terms of\na Secondary License.\n\n1.6. \"Executable Form\"\n\nmeans any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\nmeans a work that combines Covered Software with other material, in a\nseparate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\nmeans this document.\n\n1.9. \"Licensable\"\n\nmeans having the right to grant, to the maximum extent possible, whether\nat the time of the initial grant or subsequently, any and all of the\nrights conveyed by this License.\n\n1.10. \"Modifications\"\n\nmeans any of the following:\n\na. any file in Source Code Form that results from an addition to,\ndeletion from, or modification of the contents of Covered Software; or\n\nb. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\nmeans any patent claim(s), including without limitation, method,\nprocess, and apparatus claims, in any patent Licensable by such\nContributor that would be infringed, but for the grant of the License,\nby the making, using, selling, offering for sale, having made, import,\nor transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\nmeans either the GNU General Public License, Version 2.0, the GNU Lesser\nGeneral Public License, Version 2.1, the GNU Affero General Public\nLicense, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\nmeans the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\nmeans an individual or a legal entity exercising rights under this\nLicense. For legal entities, \"You\" includes any entity that controls, is\ncontrolled by, or is under common control with You. For purposes of this\ndefinition, \"control\" means (a) the power, direct or indirect, to cause\nthe direction or management of such entity, whether by contract or\notherwise, or (b) ownership of more than fifty percent (50%) of the\noutstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\na. under intellectual property rights (other than patent or trademark)\nLicensable by such Contributor to use, reproduce, make available,\nmodify, display, perform, distribute, and otherwise exploit its\nContributions, either on an unmodified basis, with Modifications, or\nas part of a Larger Work; and\n\nb. under Patent Claims of such Contributor to make, use, sell, offer for\nsale, have made, import, and otherwise transfer either its\nContributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\na. for any code that a Contributor has removed from Covered Software; or\n\nb. for infringements caused by: (i) Your and any other third party's\nmodifications of Covered Software, or (ii) the combination of its\nContributions with other software (except as part of its Contributor\nVersion); or\n\nc. under Patent Claims infringed by Covered Software in the absence of\nits Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights to\ngrant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in\nSection 2.1.\n\n\n3. Responsibilities\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\na. such Covered Software must also be made available in Source Code Form,\nas described in Section 3.1, and You must inform recipients of the\nExecutable Form how they can obtain a copy of such Source Code Form by\nreasonable means in a timely manner, at a charge no more than the cost\nof distribution to the recipient; and\n\nb. You may distribute such Executable Form under the terms of this\nLicense, or sublicense it under different terms, provided that the\nlicense for the Executable Form does not attempt to limit or alter the\nrecipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty, or\nlimitations of liability) contained within the Source Code Form of the\nCovered Software, except that You may alter any license notices to the\nextent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n\nIf it is impossible for You to comply with any of the terms of this License\nwith respect to some or all of the Covered Software due to statute,\njudicial order, or regulation then You must: (a) comply with the terms of\nthis License to the maximum extent possible; and (b) describe the\nlimitations and the code they affect. Such description must be placed in a\ntext file included with all distributions of the Covered Software under\nthis License. Except to the extent prohibited by statute or regulation,\nsuch description must be sufficiently detailed for a recipient of ordinary\nskill to be able to understand it.\n\n5. Termination\n\n5.1. The rights granted under this License will terminate automatically if You\nfail to comply with any of its terms. However, if You become compliant,\nthen the rights granted under this License from a particular Contributor\nare reinstated (a) provisionally, unless and until such Contributor\nexplicitly and finally terminates Your grants, and (b) on an ongoing\nbasis, if such Contributor fails to notify You of the non-compliance by\nsome reasonable means prior to 60 days after You have come back into\ncompliance. Moreover, Your grants from a particular Contributor are\nreinstated on an ongoing basis if such Contributor notifies You of the\nnon-compliance by some reasonable means, this is the first time You have\nreceived notice of non-compliance with this License from such\nContributor, and You become compliant prior to 30 days after Your receipt\nof the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user\nlicense agreements (excluding distributors and resellers) which have been\nvalidly granted by You or Your distributors under this License prior to\ntermination shall survive termination.\n\n6. Disclaimer of Warranty\n\nCovered Software is provided under this License on an \"as is\" basis,\nwithout warranty of any kind, either expressed, implied, or statutory,\nincluding, without limitation, warranties that the Covered Software is free\nof defects, merchantable, fit for a particular purpose or non-infringing.\nThe entire risk as to the quality and performance of the Covered Software\nis with You. Should any Covered Software prove defective in any respect,\nYou (not any Contributor) assume the cost of any necessary servicing,\nrepair, or correction. This disclaimer of warranty constitutes an essential\npart of this License. No use of any Covered Software is authorized under\nthis License except under this disclaimer.\n\n7. Limitation of Liability\n\nUnder no circumstances and under no legal theory, whether tort (including\nnegligence), contract, or otherwise, shall any Contributor, or anyone who\ndistributes Covered Software as permitted above, be liable to You for any\ndirect, indirect, special, incidental, or consequential damages of any\ncharacter including, without limitation, damages for lost profits, loss of\ngoodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses, even if such party shall have been\ninformed of the possibility of such damages. This limitation of liability\nshall not apply to liability for death or personal injury resulting from\nsuch party's negligence to the extent applicable law prohibits such\nlimitation. Some jurisdictions do not allow the exclusion or limitation of\nincidental or consequential damages, so this exclusion and limitation may\nnot apply to You.\n\n8. Litigation\n\nAny litigation relating to this License may be brought only in the courts\nof a jurisdiction where the defendant maintains its principal place of\nbusiness and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions. Nothing\nin this Section shall prevent a party's ability to bring cross-claims or\ncounter-claims.\n\n9. Miscellaneous\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides that\nthe language of a contract shall be construed against the drafter shall not\nbe used to construe this License against a Contributor.\n\n\n10. Versions of the License\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses If You choose to distribute Source Code Form that is\nIncompatible With Secondary Licenses under the terms of this version of\nthe License, the notice described in Exhibit B of this License must be\nattached.\n\nExhibit A - Source Code Form License Notice\n\nThis Source Code Form is subject to the\nterms of the Mozilla Public License, v.\n2.0. If a copy of the MPL was not\ndistributed with this file, You can\nobtain one at\nhttp://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular file,\nthen You may include the notice in a location (such as a LICENSE file in a\nrelevant directory) where a recipient would be likely to look for such a\nnotice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n\nThis Source Code Form is \"Incompatible\nWith Secondary Licenses\", as defined by\nthe Mozilla Public License, v. 2.0.\n\n" + }, + { + "name": "github.com/hashicorp/go-version", + "body": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. โ€œContributorโ€\n\nmeans each individual or legal entity that creates, contributes to the\ncreation of, or owns Covered Software.\n\n1.2. โ€œContributor Versionโ€\n\nmeans the combination of the Contributions of others (if any) used by a\nContributor and that particular Contributorโ€™s Contribution.\n\n1.3. โ€œContributionโ€\n\nmeans Covered Software of a particular Contributor.\n\n1.4. โ€œCovered Softwareโ€\n\nmeans Source Code Form to which the initial Contributor has attached the\nnotice in Exhibit A, the Executable Form of such Source Code Form, and\nModifications of such Source Code Form, in each case including portions\nthereof.\n\n1.5. โ€œIncompatible With Secondary Licensesโ€\nmeans\n\na. that the initial Contributor has attached the notice described in\nExhibit B to the Covered Software; or\n\nb. that the Covered Software was made available under the terms of version\n1.1 or earlier of the License, but not also under the terms of a\nSecondary License.\n\n1.6. โ€œExecutable Formโ€\n\nmeans any form of the work other than Source Code Form.\n\n1.7. โ€œLarger Workโ€\n\nmeans a work that combines Covered Software with other material, in a separate\nfile or files, that is not Covered Software.\n\n1.8. โ€œLicenseโ€\n\nmeans this document.\n\n1.9. โ€œLicensableโ€\n\nmeans having the right to grant, to the maximum extent possible, whether at the\ntime of the initial grant or subsequently, any and all of the rights conveyed by\nthis License.\n\n1.10. โ€œModificationsโ€\n\nmeans any of the following:\n\na. any file in Source Code Form that results from an addition to, deletion\nfrom, or modification of the contents of Covered Software; or\n\nb. any new file in Source Code Form that contains any Covered Software.\n\n1.11. โ€œPatent Claimsโ€ of a Contributor\n\nmeans any patent claim(s), including without limitation, method, process,\nand apparatus claims, in any patent Licensable by such Contributor that\nwould be infringed, but for the grant of the License, by the making,\nusing, selling, offering for sale, having made, import, or transfer of\neither its Contributions or its Contributor Version.\n\n1.12. โ€œSecondary Licenseโ€\n\nmeans either the GNU General Public License, Version 2.0, the GNU Lesser\nGeneral Public License, Version 2.1, the GNU Affero General Public\nLicense, Version 3.0, or any later versions of those licenses.\n\n1.13. โ€œSource Code Formโ€\n\nmeans the form of the work preferred for making modifications.\n\n1.14. โ€œYouโ€ (or โ€œYourโ€)\n\nmeans an individual or a legal entity exercising rights under this\nLicense. For legal entities, โ€œYouโ€ includes any entity that controls, is\ncontrolled by, or is under common control with You. For purposes of this\ndefinition, โ€œcontrolโ€ means (a) the power, direct or indirect, to cause\nthe direction or management of such entity, whether by contract or\notherwise, or (b) ownership of more than fifty percent (50%) of the\noutstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\na. under intellectual property rights (other than patent or trademark)\nLicensable by such Contributor to use, reproduce, make available,\nmodify, display, perform, distribute, and otherwise exploit its\nContributions, either on an unmodified basis, with Modifications, or as\npart of a Larger Work; and\n\nb. under Patent Claims of such Contributor to make, use, sell, offer for\nsale, have made, import, and otherwise transfer either its Contributions\nor its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution become\neffective for each Contribution on the date the Contributor first distributes\nsuch Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under this\nLicense. No additional rights or licenses will be implied from the distribution\nor licensing of Covered Software under this License. Notwithstanding Section\n2.1(b) above, no patent license is granted by a Contributor:\n\na. for any code that a Contributor has removed from Covered Software; or\n\nb. for infringements caused by: (i) Your and any other third partyโ€™s\nmodifications of Covered Software, or (ii) the combination of its\nContributions with other software (except as part of its Contributor\nVersion); or\n\nc. under Patent Claims infringed by Covered Software in the absence of its\nContributions.\n\nThis License does not grant any rights in the trademarks, service marks, or\nlogos of any Contributor (except as may be necessary to comply with the\nnotice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this License\n(see Section 10.2) or under the terms of a Secondary License (if permitted\nunder the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its Contributions\nare its original creation(s) or it has sufficient rights to grant the\nrights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under applicable\ncopyright doctrines of fair use, fair dealing, or other equivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in\nSection 2.1.\n\n\n3. Responsibilities\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under the\nterms of this License. You must inform recipients that the Source Code Form\nof the Covered Software is governed by the terms of this License, and how\nthey can obtain a copy of this License. You may not attempt to alter or\nrestrict the recipientsโ€™ rights in the Source Code Form.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\na. such Covered Software must also be made available in Source Code Form,\nas described in Section 3.1, and You must inform recipients of the\nExecutable Form how they can obtain a copy of such Source Code Form by\nreasonable means in a timely manner, at a charge no more than the cost\nof distribution to the recipient; and\n\nb. You may distribute such Executable Form under the terms of this License,\nor sublicense it under different terms, provided that the license for\nthe Executable Form does not attempt to limit or alter the recipientsโ€™\nrights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for the\nCovered Software. If the Larger Work is a combination of Covered Software\nwith a work governed by one or more Secondary Licenses, and the Covered\nSoftware is not Incompatible With Secondary Licenses, this License permits\nYou to additionally distribute such Covered Software under the terms of\nsuch Secondary License(s), so that the recipient of the Larger Work may, at\ntheir option, further distribute the Covered Software under the terms of\neither this License or such Secondary License(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices (including\ncopyright notices, patent notices, disclaimers of warranty, or limitations\nof liability) contained within the Source Code Form of the Covered\nSoftware, except that You may alter any license notices to the extent\nrequired to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on behalf\nof any Contributor. You must make it absolutely clear that any such\nwarranty, support, indemnity, or liability obligation is offered by You\nalone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n\nIf it is impossible for You to comply with any of the terms of this License\nwith respect to some or all of the Covered Software due to statute, judicial\norder, or regulation then You must: (a) comply with the terms of this License\nto the maximum extent possible; and (b) describe the limitations and the code\nthey affect. Such description must be placed in a text file included with all\ndistributions of the Covered Software under this License. Except to the\nextent prohibited by statute or regulation, such description must be\nsufficiently detailed for a recipient of ordinary skill to be able to\nunderstand it.\n\n5. Termination\n\n5.1. The rights granted under this License will terminate automatically if You\nfail to comply with any of its terms. However, if You become compliant,\nthen the rights granted under this License from a particular Contributor\nare reinstated (a) provisionally, unless and until such Contributor\nexplicitly and finally terminates Your grants, and (b) on an ongoing basis,\nif such Contributor fails to notify You of the non-compliance by some\nreasonable means prior to 60 days after You have come back into compliance.\nMoreover, Your grants from a particular Contributor are reinstated on an\nongoing basis if such Contributor notifies You of the non-compliance by\nsome reasonable means, this is the first time You have received notice of\nnon-compliance with this License from such Contributor, and You become\ncompliant prior to 30 days after Your receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions, counter-claims,\nand cross-claims) alleging that a Contributor Version directly or\nindirectly infringes any patent, then the rights granted to You by any and\nall Contributors for the Covered Software under Section 2.1 of this License\nshall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user\nlicense agreements (excluding distributors and resellers) which have been\nvalidly granted by You or Your distributors under this License prior to\ntermination shall survive termination.\n\n6. Disclaimer of Warranty\n\nCovered Software is provided under this License on an โ€œas isโ€ basis, without\nwarranty of any kind, either expressed, implied, or statutory, including,\nwithout limitation, warranties that the Covered Software is free of defects,\nmerchantable, fit for a particular purpose or non-infringing. The entire\nrisk as to the quality and performance of the Covered Software is with You.\nShould any Covered Software prove defective in any respect, You (not any\nContributor) assume the cost of any necessary servicing, repair, or\ncorrection. This disclaimer of warranty constitutes an essential part of this\nLicense. No use of any Covered Software is authorized under this License\nexcept under this disclaimer.\n\n7. Limitation of Liability\n\nUnder no circumstances and under no legal theory, whether tort (including\nnegligence), contract, or otherwise, shall any Contributor, or anyone who\ndistributes Covered Software as permitted above, be liable to You for any\ndirect, indirect, special, incidental, or consequential damages of any\ncharacter including, without limitation, damages for lost profits, loss of\ngoodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses, even if such party shall have been\ninformed of the possibility of such damages. This limitation of liability\nshall not apply to liability for death or personal injury resulting from such\npartyโ€™s negligence to the extent applicable law prohibits such limitation.\nSome jurisdictions do not allow the exclusion or limitation of incidental or\nconsequential damages, so this exclusion and limitation may not apply to You.\n\n8. Litigation\n\nAny litigation relating to this License may be brought only in the courts of\na jurisdiction where the defendant maintains its principal place of business\nand such litigation shall be governed by laws of that jurisdiction, without\nreference to its conflict-of-law provisions. Nothing in this Section shall\nprevent a partyโ€™s ability to bring cross-claims or counter-claims.\n\n9. Miscellaneous\n\nThis License represents the complete agreement concerning the subject matter\nhereof. If any provision of this License is held to be unenforceable, such\nprovision shall be reformed only to the extent necessary to make it\nenforceable. Any law or regulation which provides that the language of a\ncontract shall be construed against the drafter shall not be used to construe\nthis License against a Contributor.\n\n\n10. Versions of the License\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version of\nthe License under which You originally received the Covered Software, or\nunder the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a modified\nversion of this License if you rename the license and remove any\nreferences to the name of the license steward (except to note that such\nmodified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n\nThis Source Code Form is subject to the\nterms of the Mozilla Public License, v.\n2.0. If a copy of the MPL was not\ndistributed with this file, You can\nobtain one at\nhttp://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular file, then\nYou may include the notice in a location (such as a LICENSE file in a relevant\ndirectory) where a recipient would be likely to look for such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - โ€œIncompatible With Secondary Licensesโ€ Notice\n\nThis Source Code Form is โ€œIncompatible\nWith Secondary Licensesโ€, as defined by\nthe Mozilla Public License, v. 2.0.\n\n" + }, + { + "name": "github.com/hashicorp/golang-lru", + "body": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\nmeans each individual or legal entity that creates, contributes to the\ncreation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\nmeans the combination of the Contributions of others (if any) used by a\nContributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\nmeans Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\nmeans Source Code Form to which the initial Contributor has attached the\nnotice in Exhibit A, the Executable Form of such Source Code Form, and\nModifications of such Source Code Form, in each case including portions\nthereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\nmeans\n\na. that the initial Contributor has attached the notice described in\nExhibit B to the Covered Software; or\n\nb. that the Covered Software was made available under the terms of\nversion 1.1 or earlier of the License, but not also under the terms of\na Secondary License.\n\n1.6. \"Executable Form\"\n\nmeans any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\nmeans a work that combines Covered Software with other material, in a\nseparate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\nmeans this document.\n\n1.9. \"Licensable\"\n\nmeans having the right to grant, to the maximum extent possible, whether\nat the time of the initial grant or subsequently, any and all of the\nrights conveyed by this License.\n\n1.10. \"Modifications\"\n\nmeans any of the following:\n\na. any file in Source Code Form that results from an addition to,\ndeletion from, or modification of the contents of Covered Software; or\n\nb. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\nmeans any patent claim(s), including without limitation, method,\nprocess, and apparatus claims, in any patent Licensable by such\nContributor that would be infringed, but for the grant of the License,\nby the making, using, selling, offering for sale, having made, import,\nor transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\nmeans either the GNU General Public License, Version 2.0, the GNU Lesser\nGeneral Public License, Version 2.1, the GNU Affero General Public\nLicense, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\nmeans the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\nmeans an individual or a legal entity exercising rights under this\nLicense. For legal entities, \"You\" includes any entity that controls, is\ncontrolled by, or is under common control with You. For purposes of this\ndefinition, \"control\" means (a) the power, direct or indirect, to cause\nthe direction or management of such entity, whether by contract or\notherwise, or (b) ownership of more than fifty percent (50%) of the\noutstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\na. under intellectual property rights (other than patent or trademark)\nLicensable by such Contributor to use, reproduce, make available,\nmodify, display, perform, distribute, and otherwise exploit its\nContributions, either on an unmodified basis, with Modifications, or\nas part of a Larger Work; and\n\nb. under Patent Claims of such Contributor to make, use, sell, offer for\nsale, have made, import, and otherwise transfer either its\nContributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\na. for any code that a Contributor has removed from Covered Software; or\n\nb. for infringements caused by: (i) Your and any other third party's\nmodifications of Covered Software, or (ii) the combination of its\nContributions with other software (except as part of its Contributor\nVersion); or\n\nc. under Patent Claims infringed by Covered Software in the absence of\nits Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights to\ngrant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in\nSection 2.1.\n\n\n3. Responsibilities\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\na. such Covered Software must also be made available in Source Code Form,\nas described in Section 3.1, and You must inform recipients of the\nExecutable Form how they can obtain a copy of such Source Code Form by\nreasonable means in a timely manner, at a charge no more than the cost\nof distribution to the recipient; and\n\nb. You may distribute such Executable Form under the terms of this\nLicense, or sublicense it under different terms, provided that the\nlicense for the Executable Form does not attempt to limit or alter the\nrecipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty, or\nlimitations of liability) contained within the Source Code Form of the\nCovered Software, except that You may alter any license notices to the\nextent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n\nIf it is impossible for You to comply with any of the terms of this License\nwith respect to some or all of the Covered Software due to statute,\njudicial order, or regulation then You must: (a) comply with the terms of\nthis License to the maximum extent possible; and (b) describe the\nlimitations and the code they affect. Such description must be placed in a\ntext file included with all distributions of the Covered Software under\nthis License. Except to the extent prohibited by statute or regulation,\nsuch description must be sufficiently detailed for a recipient of ordinary\nskill to be able to understand it.\n\n5. Termination\n\n5.1. The rights granted under this License will terminate automatically if You\nfail to comply with any of its terms. However, if You become compliant,\nthen the rights granted under this License from a particular Contributor\nare reinstated (a) provisionally, unless and until such Contributor\nexplicitly and finally terminates Your grants, and (b) on an ongoing\nbasis, if such Contributor fails to notify You of the non-compliance by\nsome reasonable means prior to 60 days after You have come back into\ncompliance. Moreover, Your grants from a particular Contributor are\nreinstated on an ongoing basis if such Contributor notifies You of the\nnon-compliance by some reasonable means, this is the first time You have\nreceived notice of non-compliance with this License from such\nContributor, and You become compliant prior to 30 days after Your receipt\nof the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user\nlicense agreements (excluding distributors and resellers) which have been\nvalidly granted by You or Your distributors under this License prior to\ntermination shall survive termination.\n\n6. Disclaimer of Warranty\n\nCovered Software is provided under this License on an \"as is\" basis,\nwithout warranty of any kind, either expressed, implied, or statutory,\nincluding, without limitation, warranties that the Covered Software is free\nof defects, merchantable, fit for a particular purpose or non-infringing.\nThe entire risk as to the quality and performance of the Covered Software\nis with You. Should any Covered Software prove defective in any respect,\nYou (not any Contributor) assume the cost of any necessary servicing,\nrepair, or correction. This disclaimer of warranty constitutes an essential\npart of this License. No use of any Covered Software is authorized under\nthis License except under this disclaimer.\n\n7. Limitation of Liability\n\nUnder no circumstances and under no legal theory, whether tort (including\nnegligence), contract, or otherwise, shall any Contributor, or anyone who\ndistributes Covered Software as permitted above, be liable to You for any\ndirect, indirect, special, incidental, or consequential damages of any\ncharacter including, without limitation, damages for lost profits, loss of\ngoodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses, even if such party shall have been\ninformed of the possibility of such damages. This limitation of liability\nshall not apply to liability for death or personal injury resulting from\nsuch party's negligence to the extent applicable law prohibits such\nlimitation. Some jurisdictions do not allow the exclusion or limitation of\nincidental or consequential damages, so this exclusion and limitation may\nnot apply to You.\n\n8. Litigation\n\nAny litigation relating to this License may be brought only in the courts\nof a jurisdiction where the defendant maintains its principal place of\nbusiness and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions. Nothing\nin this Section shall prevent a party's ability to bring cross-claims or\ncounter-claims.\n\n9. Miscellaneous\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides that\nthe language of a contract shall be construed against the drafter shall not\nbe used to construe this License against a Contributor.\n\n\n10. Versions of the License\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses If You choose to distribute Source Code Form that is\nIncompatible With Secondary Licenses under the terms of this version of\nthe License, the notice described in Exhibit B of this License must be\nattached.\n\nExhibit A - Source Code Form License Notice\n\nThis Source Code Form is subject to the\nterms of the Mozilla Public License, v.\n2.0. If a copy of the MPL was not\ndistributed with this file, You can\nobtain one at\nhttp://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular file,\nthen You may include the notice in a location (such as a LICENSE file in a\nrelevant directory) where a recipient would be likely to look for such a\nnotice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n\nThis Source Code Form is \"Incompatible\nWith Secondary Licenses\", as defined by\nthe Mozilla Public License, v. 2.0.\n" + }, + { + "name": "github.com/huandu/xstrings", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Huan Du\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/jaytaylor/html2text", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Jay Taylor\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/josharian/intern", + "body": "MIT License\n\nCopyright (c) 2019 Josh Bleecher Snyder\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/json-iterator/go", + "body": "MIT License\n\nCopyright (c) 2016 json-iterator\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/kballard/go-shellquote", + "body": "Copyright (C) 2014 Kevin Ballard\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\nOR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/keybase/go-crypto", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/klauspost/compress", + "body": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2019 Klaus Post. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n------------------\n\nFiles: gzhttp/*\n\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright 2016-2017 The New York Times Company\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n------------------\n\nFiles: s2/cmd/internal/readahead/*\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n---------------------\nFiles: snappy/*\nFiles: internal/snapref/*\n\nCopyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-----------------\n\nFiles: s2/cmd/internal/filepathx/*\n\nCopyright 2016 The filepathx Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/klauspost/compress/internal/snapref", + "body": "Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/klauspost/compress/s2", + "body": "Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.\nCopyright (c) 2019 Klaus Post. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/klauspost/compress/zstd/internal/xxhash", + "body": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/klauspost/cpuid/v2", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/klauspost/pgzip", + "body": "MIT License\n\nCopyright (c) 2014 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/lib/pq", + "body": "Copyright (c) 2011-2013, 'pq' Contributors\nPortions Copyright (C) 2011 Blake Mizerany\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/libdns/libdns", + "body": "MIT License\n\nCopyright (c) 2020 Matthew Holt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/mailru/easyjson", + "body": "Copyright (c) 2016 Mail.Ru Group\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/markbates/going/defaults", + "body": "Copyright (c) 2014 Mark Bates\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/markbates/goth", + "body": "Copyright (c) 2014 Mark Bates\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/mattn/go-isatty", + "body": "Copyright (c) Yasuhiro MATSUMOTO \n\nMIT License (Expat)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/mattn/go-runewidth", + "body": "The MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/matttproud/golang_protobuf_extensions/pbutil", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"{}\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright {yyyy} {name of copyright owner}\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/matttproud/golang_protobuf_extensions/pbutil", + "body": "Copyright 2012 Matt T. Proud (matt.proud@gmail.com)\n" + }, + { + "name": "github.com/mholt/acmez", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/mholt/archiver/v3", + "body": "MIT License\n\nCopyright (c) 2016 Matthew Holt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, + { + "name": "github.com/microcosm-cc/bluemonday", + "body": "SPDX short identifier: BSD-3-Clause\nhttps://opensource.org/licenses/BSD-3-Clause\n\nCopyright (c) 2014, David Kitchen \n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* Neither the name of the organisation (Microcosm) nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/miekg/dns", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nAs this is fork of the official Go code the same license applies.\nExtensions of the original work are copyright (c) 2011 Miek Gieben\n" + }, + { + "name": "github.com/minio/md5-simd", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/minio/minio-go/v7", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/minio/minio-go/v7", + "body": "MinIO Cloud Storage, (C) 2014-2020 MinIO, Inc.\n\nThis product includes software developed at MinIO, Inc.\n(https://min.io/).\n\nThe MinIO project contains unmodified/modified subcomponents too with\nseparate copyright notices and license terms. Your use of the source\ncode for these subcomponents is subject to the terms and conditions\nof Apache License Version 2.0\n" + }, + { + "name": "github.com/minio/sha256-simd", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/mitchellh/mapstructure", + "body": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/modern-go/concurrent", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/modern-go/reflect2", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/nfnt/resize", + "body": "Copyright (c) 2012, Jan Schlicht \n\nPermission to use, copy, modify, and/or distribute this software for any purpose\nwith or without fee is hereby granted, provided that the above copyright notice\nand this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\nOF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\nTHIS SOFTWARE.\n" + }, + { + "name": "github.com/niklasfasching/go-org/org", + "body": "MIT License\n\nCopyright (c) 2018 Niklas Fasching\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/nwaples/rardecode", + "body": "Copyright (c) 2015, Nicholas Waples\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/olekukonko/tablewriter", + "body": "Copyright (C) 2014 by Oleku Konko\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/oliamb/cutter", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Olivier Amblet\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/olivere/elastic/v7", + "body": "The MIT License (MIT)\nCopyright ยฉ 2012-2015 Oliver Eilhard\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the โ€œSoftwareโ€), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED โ€œAS ISโ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n" + }, + { + "name": "github.com/olivere/elastic/v7/uritemplates", + "body": "Copyright (c) 2013 Joshua Tacoma\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/pierrec/lz4/v4", + "body": "Copyright (c) 2015, Pierre Curto\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* Neither the name of xxHash nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n" + }, + { + "name": "github.com/pkg/errors", + "body": "Copyright (c) 2015, Dave Cheney \nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/pquerna/otp", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/pquerna/otp", + "body": "otp\nCopyright (c) 2014, Paul Querna\n\nThis product includes software developed by\nPaul Querna (http://paul.querna.org/).\n" + }, + { + "name": "github.com/prometheus/client_golang/prometheus", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/prometheus/client_golang/prometheus", + "body": "Prometheus instrumentation library for Go applications\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\nThe following components are included in this product:\n\nperks - a fork of https://github.com/bmizerany/perks\nhttps://github.com/beorn7/perks\nCopyright 2013-2015 Blake Mizerany, Bjรถrn Rabenstein\nSee https://github.com/beorn7/perks/blob/master/README.md for license details.\n\nGo support for Protocol Buffers - Google's data interchange format\nhttp://github.com/golang/protobuf/\nCopyright 2010 The Go Authors\nSee source code for license details.\n\nSupport for streaming Protocol Buffer messages for the Go language (golang).\nhttps://github.com/matttproud/golang_protobuf_extensions\nCopyright 2013 Matt T. Proud\nLicensed under the Apache License, Version 2.0\n" + }, + { + "name": "github.com/prometheus/client_model/go", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/prometheus/client_model/go", + "body": "Data model artifacts for Prometheus.\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n" + }, + { + "name": "github.com/prometheus/common", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/prometheus/common", + "body": "Common libraries shared by Prometheus Go components.\nCopyright 2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n" + }, + { + "name": "github.com/prometheus/procfs", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"[]\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/prometheus/procfs", + "body": "procfs provides functions to retrieve system, kernel and process\nmetrics from the pseudo-filesystem proc.\n\nCopyright 2014-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n" + }, + { + "name": "github.com/rivo/uniseg", + "body": "MIT License\n\nCopyright (c) 2019 Oliver Kuederle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/rs/xid", + "body": "Copyright (c) 2015 Olivier Poitrey \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/russross/blackfriday/v2", + "body": "Blackfriday is distributed under the Simplified BSD License:\n\n> Copyright ยฉ 2011 Russ Ross\n> All rights reserved.\n>\n> Redistribution and use in source and binary forms, with or without\n> modification, are permitted provided that the following conditions\n> are met:\n>\n> 1. Redistributions of source code must retain the above copyright\n> notice, this list of conditions and the following disclaimer.\n>\n> 2. Redistributions in binary form must reproduce the above\n> copyright notice, this list of conditions and the following\n> disclaimer in the documentation and/or other materials provided with\n> the distribution.\n>\n> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n> \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n> POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/santhosh-tekuri/jsonschema/v5", + "body": "\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability." + }, + { + "name": "github.com/sergi/go-diff/diffmatchpatch", + "body": "Copyright (c) 2012-2016 The go-diff Authors. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n\n" + }, + { + "name": "github.com/ssor/bom", + "body": "MIT License\n\nCopyright (c) 2017 Asher\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/syndtr/goleveldb/leveldb", + "body": "Copyright 2012 Suryandaru Triandana \nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/tstranex/u2f", + "body": "The MIT License (MIT)\n\nCopyright (c) 2015 The Go FIDO U2F Library Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "github.com/ulikunitz/xz", + "body": "Copyright (c) 2014-2021 Ulrich Kunitz\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* My name, Ulrich Kunitz, may not be used to endorse or promote products\nderived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "github.com/unknwon/com", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + }, + { + "name": "github.com/unrolled/render", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Cory Jacobsen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "github.com/urfave/cli", + "body": "MIT License\n\nCopyright (c) 2016 Jeremy Saenz & Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/valyala/fastjson", + "body": "The MIT License (MIT)\n\nCopyright (c) 2018 Aliaksandr Valialkin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/x448/float16", + "body": "MIT License\n\nCopyright (c) 2019 Montgomery Edwardsโดโดโธ and Faye Amacker\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n" + }, + { + "name": "github.com/xanzy/go-gitlab", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"{}\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright {yyyy} {name of copyright owner}\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/yohcop/openid-go", + "body": "Copyright 2015 Yohann Coppel\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "github.com/yuin/goldmark-highlighting", + "body": "MIT License\n\nCopyright (c) 2019 Yusuke Inuzuka\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/yuin/goldmark-meta", + "body": "MIT License\n\nCopyright (c) 2019 Yusuke Inuzuka\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "github.com/yuin/goldmark", + "body": "MIT License\n\nCopyright (c) 2019 Yusuke Inuzuka\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + { + "name": "go.etcd.io/bbolt", + "body": "The MIT License (MIT)\n\nCopyright (c) 2013 Ben Johnson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "go.jolheiser.com/hcaptcha", + "body": "Copyright 2020 John Olheiser\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + }, + { + "name": "go.jolheiser.com/pwn", + "body": "Copyright 2020 John Olheiser\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + }, + { + "name": "go.uber.org/atomic", + "body": "Copyright (c) 2016 Uber Technologies, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "go.uber.org/multierr", + "body": "Copyright (c) 2017-2021 Uber Technologies, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "go.uber.org/zap", + "body": "Copyright (c) 2016-2017 Uber Technologies, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "golang.org/x/crypto", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/mod/semver", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/net", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/oauth2", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/sys", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/text", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "golang.org/x/time/rate", + "body": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "google.golang.org/protobuf", + "body": "Copyright (c) 2018 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "gopkg.in/gomail.v2", + "body": "The MIT License (MIT)\n\nCopyright (c) 2014 Alexandre Cesaro\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, + { + "name": "gopkg.in/ini.v1", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\nCopyright 2014 Unknwon\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "gopkg.in/yaml.v2", + "body": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction,\nand distribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by\nthe copyright owner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all\nother entities that control, are controlled by, or are under common\ncontrol with that entity. For the purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the\ndirection or management of such entity, whether by contract or\notherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity\nexercising permissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications,\nincluding but not limited to software source code, documentation\nsource, and configuration files.\n\n\"Object\" form shall mean any form resulting from mechanical\ntransformation or translation of a Source form, including but\nnot limited to compiled object code, generated documentation,\nand conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or\nObject form, made available under the License, as indicated by a\ncopyright notice that is included in or attached to the work\n(an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object\nform, that is based on (or derived from) the Work and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship. For the purposes\nof this License, Derivative Works shall not include works that remain\nseparable from, or merely link (or bind by name) to the interfaces of,\nthe Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including\nthe original version of the Work and any modifications or additions\nto that Work or Derivative Works thereof, that is intentionally\nsubmitted to Licensor for inclusion in the Work by the copyright owner\nor by an individual or Legal Entity authorized to submit on behalf of\nthe copyright owner. For the purposes of this definition, \"submitted\"\nmeans any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems,\nand issue tracking systems that are managed by, or on behalf of, the\nLicensor for the purpose of discussing and improving the Work, but\nexcluding communication that is conspicuously marked or otherwise\ndesignated in writing by the copyright owner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity\non behalf of whom a Contribution has been received by Licensor and\nsubsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\ncopyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the\nWork and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\nthis License, each Contributor hereby grants to You a perpetual,\nworldwide, non-exclusive, no-charge, royalty-free, irrevocable\n(except as stated in this section) patent license to make, have made,\nuse, offer to sell, sell, import, and otherwise transfer the Work,\nwhere such license applies only to those patent claims licensable\nby such Contributor that are necessarily infringed by their\nContribution(s) alone or by combination of their Contribution(s)\nwith the Work to which such Contribution(s) was submitted. If You\ninstitute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work\nor a Contribution incorporated within the Work constitutes direct\nor contributory patent infringement, then any patent licenses\ngranted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\nWork or Derivative Works thereof in any medium, with or without\nmodifications, and in Source or Object form, provided that You\nmeet the following conditions:\n\n(a) You must give any other recipients of the Work or\nDerivative Works a copy of this License; and\n\n(b) You must cause any modified files to carry prominent notices\nstating that You changed the files; and\n\n(c) You must retain, in the Source form of any Derivative Works\nthat You distribute, all copyright, patent, trademark, and\nattribution notices from the Source form of the Work,\nexcluding those notices that do not pertain to any part of\nthe Derivative Works; and\n\n(d) If the Work includes a \"NOTICE\" text file as part of its\ndistribution, then any Derivative Works that You distribute must\ninclude a readable copy of the attribution notices contained\nwithin such NOTICE file, excluding those notices that do not\npertain to any part of the Derivative Works, in at least one\nof the following places: within a NOTICE text file distributed\nas part of the Derivative Works; within the Source form or\ndocumentation, if provided along with the Derivative Works; or,\nwithin a display generated by the Derivative Works, if and\nwherever such third-party notices normally appear. The contents\nof the NOTICE file are for informational purposes only and\ndo not modify the License. You may add Your own attribution\nnotices within Derivative Works that You distribute, alongside\nor as an addendum to the NOTICE text from the Work, provided\nthat such additional attribution notices cannot be construed\nas modifying the License.\n\nYou may add Your own copyright statement to Your modifications and\nmay provide additional or different license terms and conditions\nfor use, reproduction, or distribution of Your modifications, or\nfor any such Derivative Works as a whole, provided Your use,\nreproduction, and distribution of the Work otherwise complies with\nthe conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\nany Contribution intentionally submitted for inclusion in the Work\nby You to the Licensor shall be under the terms and conditions of\nthis License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify\nthe terms of any separate license agreement you may have executed\nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\nnames, trademarks, service marks, or product names of the Licensor,\nexcept as required for reasonable and customary use in describing the\norigin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\nagreed to in writing, Licensor provides the Work (and each\nContributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\nimplied, including, without limitation, any warranties or conditions\nof TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\nPARTICULAR PURPOSE. You are solely responsible for determining the\nappropriateness of using or redistributing the Work and assume any\nrisks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise,\nunless required by applicable law (such as deliberate and grossly\nnegligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special,\nincidental, or consequential damages of any character arising as a\nresult of this License or out of the use or inability to use the\nWork (including but not limited to damages for loss of goodwill,\nwork stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses), even if such Contributor\nhas been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\nthe Work or Derivative Works thereof, You may choose to offer,\nand charge a fee for, acceptance of support, warranty, indemnity,\nor other liability obligations and/or rights consistent with this\nLicense. However, in accepting such obligations, You may act only\non Your own behalf and on Your sole responsibility, not on behalf\nof any other Contributor, and only if You agree to indemnify,\ndefend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason\nof your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\nTo apply the Apache License to your work, attach the following\nboilerplate notice, with the fields enclosed by brackets \"{}\"\nreplaced with your own identifying information. (Don't include\nthe brackets!) The text should be enclosed in the appropriate\ncomment syntax for the file format. We also recommend that a\nfile or class name and description of purpose be included on the\nsame \"printed page\" as the copyright notice for easier\nidentification within third-party archives.\n\nCopyright {yyyy} {name of copyright owner}\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "gopkg.in/yaml.v2", + "body": "Copyright 2011-2016 Canonical Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" + }, + { + "name": "mvdan.cc/xurls/v2", + "body": "Copyright (c) 2015, Daniel Martรญ. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n* Neither the name of the copyright holder nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "strk.kbt.io/projects/go/libravatar", + "body": "Copyright (c) 2016 Sandro Santilli \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, + { + "name": "xorm.io/builder", + "body": "Copyright (c) 2016 The Xorm Authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* Neither the name of the {organization} nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, + { + "name": "xorm.io/xorm", + "body": "Copyright (c) 2013 - 2015 The Xorm Authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n* Neither the name of the {organization} nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + } +] \ No newline at end of file diff --git a/build/code-batch-process.go b/build/code-batch-process.go index 0f8dbd40f..24b13470a 100644 --- a/build/code-batch-process.go +++ b/build/code-batch-process.go @@ -61,7 +61,7 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error) "build", "cmd", "contrib", - "integrations", + "tests", "models", "modules", "routers", @@ -71,8 +71,8 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error) co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`)) co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`.*\bbindata\.go$`)) - co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/gitea-repositories-meta`)) - co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/migration-test`)) + co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/gitea-repositories-meta`)) + co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`tests/integration/migration-test`)) co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`modules/git/tests`)) co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/fixtures`)) co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/migrations/fixtures`)) diff --git a/build/generate-emoji.go b/build/generate-emoji.go index a22f2a457..4ad6649b2 100644 --- a/build/generate-emoji.go +++ b/build/generate-emoji.go @@ -214,8 +214,7 @@ const hdr = ` package emoji -// Code generated by gen.go. DO NOT EDIT. +// Code generated by build/generate-emoji.go. DO NOT EDIT. // Sourced from %s -// var GemojiData = %#v ` diff --git a/build/generate-go-licenses.js b/build/generate-go-licenses.js new file mode 100644 index 000000000..a645e594b --- /dev/null +++ b/build/generate-go-licenses.js @@ -0,0 +1,30 @@ +#!/usr/bin/env node +import fastGlob from 'fast-glob'; +import {fileURLToPath} from 'url'; +import {readFileSync, writeFileSync} from 'fs'; +import wrapAnsi from 'wrap-ansi'; +import {join, dirname} from 'path'; + +const base = process.argv[2]; +const out = process.argv[3]; + +function exit(err) { + if (err) console.error(err); + process.exit(err ? 1 : 0); +} + +async function main() { + const data = fastGlob.sync('**/*', { + cwd: fileURLToPath(new URL(`../${base}`, import.meta.url)), + }).filter((path) => { + return /\/((UN)?LICEN(S|C)E|COPYING|NOTICE)/i.test(path); + }).sort().map((path) => { + return { + name: dirname(path), + body: wrapAnsi(readFileSync(join(base, path), 'utf8') || '', 80) + }; + }); + writeFileSync(out, JSON.stringify(data, null, 2)); +} + +main().then(exit).catch(exit); diff --git a/build/generate-licenses.go b/build/generate-licenses.go index 02b41a229..9a111bc81 100644 --- a/build/generate-licenses.go +++ b/build/generate-licenses.go @@ -39,6 +39,14 @@ func main() { defer util.Remove(file.Name()) + if err := os.RemoveAll(destination); err != nil { + log.Fatalf("Cannot clean destination folder: %v", err) + } + + if err := os.MkdirAll(destination, 0o755); err != nil { + log.Fatalf("Cannot create destination: %v", err) + } + req, err := http.NewRequest("GET", url, nil) if err != nil { log.Fatalf("Failed to download archive. %s", err) diff --git a/build/gitea-format-imports.go b/build/gitea-format-imports.go deleted file mode 100644 index c685ae68e..000000000 --- a/build/gitea-format-imports.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -//go:build ignore - -package main - -import ( - "log" - "os" - - "code.gitea.io/gitea/build/codeformat" -) - -func main() { - if len(os.Args) <= 1 { - log.Fatalf("Usage: gitea-format-imports [files...]") - } - - for _, file := range os.Args[1:] { - if err := codeformat.FormatGoImports(file); err != nil { - log.Fatalf("can not format file %s, err=%v", file, err) - } - } -} diff --git a/cmd/admin.go b/cmd/admin.go index 6c2a8626c..2cf63d384 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -13,9 +13,8 @@ import ( "strings" "text/tabwriter" - "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" - "code.gitea.io/gitea/models/auth" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -593,12 +592,12 @@ func runCreateUser(c *cli.Context) error { } if c.Bool("access-token") { - t := &models.AccessToken{ + t := &auth_model.AccessToken{ Name: "gitea-admin", UID: u.ID, } - if err := models.NewAccessToken(t); err != nil { + if err := auth_model.NewAccessToken(t); err != nil { return err } @@ -700,12 +699,12 @@ func runGenerateAccessToken(c *cli.Context) error { return err } - t := &models.AccessToken{ + t := &auth_model.AccessToken{ Name: c.String("token-name"), UID: user.ID, } - if err := models.NewAccessToken(t); err != nil { + if err := auth_model.NewAccessToken(t); err != nil { return err } @@ -779,9 +778,9 @@ func runRepoSyncReleases(_ *cli.Context) error { } func getReleaseCount(id int64) (int64, error) { - return models.GetReleaseCountByRepoID( + return repo_model.GetReleaseCountByRepoID( id, - models.FindReleasesOptions{ + repo_model.FindReleasesOptions{ IncludeTags: true, }, ) @@ -844,8 +843,8 @@ func runAddOauth(c *cli.Context) error { return err } - return auth.CreateSource(&auth.Source{ - Type: auth.OAuth2, + return auth_model.CreateSource(&auth_model.Source{ + Type: auth_model.OAuth2, Name: c.String("name"), IsActive: true, Cfg: parseOAuth2Config(c), @@ -864,7 +863,7 @@ func runUpdateOauth(c *cli.Context) error { return err } - source, err := auth.GetSourceByID(c.Int64("id")) + source, err := auth_model.GetSourceByID(c.Int64("id")) if err != nil { return err } @@ -944,7 +943,7 @@ func runUpdateOauth(c *cli.Context) error { oAuth2Config.CustomURLMapping = customURLMapping source.Cfg = oAuth2Config - return auth.UpdateSource(source) + return auth_model.UpdateSource(source) } func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error { @@ -1015,8 +1014,8 @@ func runAddSMTP(c *cli.Context) error { smtpConfig.Auth = "PLAIN" } - return auth.CreateSource(&auth.Source{ - Type: auth.SMTP, + return auth_model.CreateSource(&auth_model.Source{ + Type: auth_model.SMTP, Name: c.String("name"), IsActive: active, Cfg: &smtpConfig, @@ -1035,7 +1034,7 @@ func runUpdateSMTP(c *cli.Context) error { return err } - source, err := auth.GetSourceByID(c.Int64("id")) + source, err := auth_model.GetSourceByID(c.Int64("id")) if err != nil { return err } @@ -1056,7 +1055,7 @@ func runUpdateSMTP(c *cli.Context) error { source.Cfg = smtpConfig - return auth.UpdateSource(source) + return auth_model.UpdateSource(source) } func runListAuth(c *cli.Context) error { @@ -1067,7 +1066,7 @@ func runListAuth(c *cli.Context) error { return err } - authSources, err := auth.Sources() + authSources, err := auth_model.Sources() if err != nil { return err } @@ -1105,7 +1104,7 @@ func runDeleteAuth(c *cli.Context) error { return err } - source, err := auth.GetSourceByID(c.Int64("id")) + source, err := auth_model.GetSourceByID(c.Int64("id")) if err != nil { return err } diff --git a/cmd/embedded.go b/cmd/embedded.go index 30fc7103d..ffdc3d6a6 100644 --- a/cmd/embedded.go +++ b/cmd/embedded.go @@ -123,7 +123,7 @@ func initEmbeddedExtractor(c *cli.Context) error { sections["public"] = §ion{Path: "public", Names: public.AssetNames, IsDir: public.AssetIsDir, Asset: public.Asset} sections["options"] = §ion{Path: "options", Names: options.AssetNames, IsDir: options.AssetIsDir, Asset: options.Asset} - sections["templates"] = §ion{Path: "templates", Names: templates.AssetNames, IsDir: templates.AssetIsDir, Asset: templates.Asset} + sections["templates"] = §ion{Path: "templates", Names: templates.BuiltinAssetNames, IsDir: templates.BuiltinAssetIsDir, Asset: templates.BuiltinAsset} for _, sec := range sections { assets = append(assets, buildAssetList(sec, pats, c)...) diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index f11cf9b11..a283f9140 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -112,11 +112,8 @@ func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) e func migrateRepoArchivers(ctx context.Context, dstStorage storage.ObjectStorage) error { return db.IterateObjects(ctx, func(archiver *repo_model.RepoArchiver) error { - p, err := archiver.RelativePath() - if err != nil { - return err - } - _, err = storage.Copy(dstStorage, p, storage.RepoArchives, p) + p := archiver.RelativePath() + _, err := storage.Copy(dstStorage, p, storage.RepoArchives, p) return err }) } diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go index e6d205e41..0d264ef5a 100644 --- a/cmd/migrate_storage_test.go +++ b/cmd/migrate_storage_test.go @@ -53,8 +53,7 @@ func TestMigratePackages(t *testing.T) { ctx := context.Background() - p, err := os.MkdirTemp(os.TempDir(), "migrated_packages") - assert.NoError(t, err) + p := t.TempDir() dstStorage, err := storage.NewLocalStorage( ctx, diff --git a/cmd/web.go b/cmd/web.go index 3bc61b044..e09560bb8 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -76,7 +76,7 @@ func runHTTPRedirector() { http.Redirect(w, r, target, http.StatusTemporaryRedirect) }) - err := runHTTP("tcp", source, "HTTP Redirector", handler) + err := runHTTP("tcp", source, "HTTP Redirector", handler, setting.RedirectorUseProxyProtocol) if err != nil { log.Fatal("Failed to start port redirection: %v", err) } @@ -126,8 +126,10 @@ func runWeb(ctx *cli.Context) error { return err } } - c := install.Routes() + installCtx, cancel := context.WithCancel(graceful.GetManager().HammerContext()) + c := install.Routes(installCtx) err := listen(c, false) + cancel() if err != nil { log.Critical("Unable to open listener for installer. Is Gitea already running?") graceful.GetManager().DoGracefulShutdown() @@ -175,7 +177,7 @@ func runWeb(ctx *cli.Context) error { } // Set up Chi routes - c := routers.NormalRoutes() + c := routers.NormalRoutes(graceful.GetManager().HammerContext()) err := listen(c, true) <-graceful.GetManager().Done() log.Info("PID: %d Gitea Web Finished", os.Getpid()) @@ -231,40 +233,38 @@ func listen(m http.Handler, handleRedirector bool) error { if handleRedirector { NoHTTPRedirector() } - err = runHTTP("tcp", listenAddr, "Web", m) + err = runHTTP("tcp", listenAddr, "Web", m, setting.UseProxyProtocol) case setting.HTTPS: if setting.EnableAcme { err = runACME(listenAddr, m) break - } else { - if handleRedirector { - if setting.RedirectOtherPort { - go runHTTPRedirector() - } else { - NoHTTPRedirector() - } - } - err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m) } + if handleRedirector { + if setting.RedirectOtherPort { + go runHTTPRedirector() + } else { + NoHTTPRedirector() + } + } + err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m, setting.UseProxyProtocol, setting.ProxyProtocolTLSBridging) case setting.FCGI: if handleRedirector { NoHTTPRedirector() } - err = runFCGI("tcp", listenAddr, "FCGI Web", m) + err = runFCGI("tcp", listenAddr, "FCGI Web", m, setting.UseProxyProtocol) case setting.HTTPUnix: if handleRedirector { NoHTTPRedirector() } - err = runHTTP("unix", listenAddr, "Web", m) + err = runHTTP("unix", listenAddr, "Web", m, setting.UseProxyProtocol) case setting.FCGIUnix: if handleRedirector { NoHTTPRedirector() } - err = runFCGI("unix", listenAddr, "Web", m) + err = runFCGI("unix", listenAddr, "Web", m, setting.UseProxyProtocol) default: log.Fatal("Invalid protocol: %s", setting.Protocol) } - if err != nil { log.Critical("Failed to start server: %v", err) } diff --git a/cmd/web_acme.go b/cmd/web_acme.go index 57b400dae..d8e550b32 100644 --- a/cmd/web_acme.go +++ b/cmd/web_acme.go @@ -113,14 +113,14 @@ func runACME(listenAddr string, m http.Handler) error { log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here) - err := runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) + err := runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)), setting.RedirectorUseProxyProtocol) if err != nil { log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err) } }() } - return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, m) + return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, m, setting.UseProxyProtocol, setting.ProxyProtocolTLSBridging) } func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/web_graceful.go b/cmd/web_graceful.go index 1618208c5..ba88cc59c 100644 --- a/cmd/web_graceful.go +++ b/cmd/web_graceful.go @@ -15,8 +15,8 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func runHTTP(network, listenAddr, name string, m http.Handler) error { - return graceful.HTTPListenAndServe(network, listenAddr, name, m) +func runHTTP(network, listenAddr, name string, m http.Handler, useProxyProtocol bool) error { + return graceful.HTTPListenAndServe(network, listenAddr, name, m, useProxyProtocol) } // NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector @@ -36,7 +36,7 @@ func NoInstallListener() { graceful.GetManager().InformCleanup() } -func runFCGI(network, listenAddr, name string, m http.Handler) error { +func runFCGI(network, listenAddr, name string, m http.Handler, useProxyProtocol bool) error { // This needs to handle stdin as fcgi point fcgiServer := graceful.NewServer(network, listenAddr, name) @@ -47,7 +47,7 @@ func runFCGI(network, listenAddr, name string, m http.Handler) error { } m.ServeHTTP(resp, req) })) - }) + }, useProxyProtocol) if err != nil { log.Fatal("Failed to start FCGI main server: %v", err) } diff --git a/cmd/web_https.go b/cmd/web_https.go index b0910ca04..aac11517a 100644 --- a/cmd/web_https.go +++ b/cmd/web_https.go @@ -129,14 +129,14 @@ var ( defaultCiphersChaChaFirst = append(defaultCiphersChaCha, defaultCiphersAES...) ) -// runHTTPs listens on the provided network address and then calls +// runHTTPS listens on the provided network address and then calls // Serve to handle requests on incoming TLS connections. // // Filenames containing a certificate and matching private key for the server must // be provided. If the certificate is signed by a certificate authority, the // certFile should be the concatenation of the server's certificate followed by the // CA's certificate. -func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error { +func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler, useProxyProtocol, proxyProtocolTLSBridging bool) error { tlsConfig := &tls.Config{} if tlsConfig.NextProtos == nil { tlsConfig.NextProtos = []string{"h2", "http/1.1"} @@ -184,9 +184,9 @@ func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handle return err } - return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m) + return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m, useProxyProtocol, proxyProtocolTLSBridging) } -func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error { - return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m) +func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler, useProxyProtocol, proxyProtocolTLSBridging bool) error { + return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m, useProxyProtocol, proxyProtocolTLSBridging) } diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index 65762a91e..85476afd0 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" gitea_git "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/external" repo_module "code.gitea.io/gitea/modules/repository" @@ -111,13 +112,13 @@ func runPR() { unittest.LoadFixtures() util.RemoveAll(setting.RepoRootPath) util.RemoveAll(repo_module.LocalCopyPath()) - unittest.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath) + unittest.CopyDir(path.Join(curDir, "tests/gitea-repositories-meta"), setting.RepoRootPath) log.Printf("[PR] Setting up router\n") // routers.GlobalInit() external.RegisterRenderers() markup.Init() - c := routers.NormalRoutes() + c := routers.NormalRoutes(graceful.GetManager().HammerContext()) log.Printf("[PR] Ready for testing !\n") log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n") diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index d8ef50f96..f0d65a65d 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -29,6 +29,18 @@ RUN_MODE = ; prod ;; The protocol the server listens on. One of 'http', 'https', 'unix' or 'fcgi'. Defaults to 'http' ;PROTOCOL = http ;; +;; Expect PROXY protocol headers on connections +;USE_PROXY_PROTOCOL = false +;; +;; Use PROXY protocol in TLS Bridging mode +;PROXY_PROTOCOL_TLS_BRIDGING = false +;; +; Timeout to wait for PROXY protocol header (set to 0 to have no timeout) +;PROXY_PROTOCOL_HEADER_TIMEOUT=5s +;; +; Accept PROXY protocol headers with UNKNOWN type +;PROXY_PROTOCOL_ACCEPT_UNKNOWN=false +;; ;; Set the domain for the server ;DOMAIN = localhost ;; @@ -51,6 +63,8 @@ RUN_MODE = ; prod ;REDIRECT_OTHER_PORT = false ;PORT_TO_REDIRECT = 80 ;; +;; expect PROXY protocol header on connections to https redirector. +;REDIRECTOR_USE_PROXY_PROTOCOL = %(USE_PROXY_PROTOCOL) ;; Minimum and maximum supported TLS versions ;SSL_MIN_VERSION=TLSv1.2 ;SSL_MAX_VERSION= @@ -76,13 +90,19 @@ RUN_MODE = ; prod ;; Do not set this variable if PROTOCOL is set to 'unix'. ;LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/ ;; +;; When making local connections pass the PROXY protocol header. +;LOCAL_USE_PROXY_PROTOCOL = %(USE_PROXY_PROTOCOL) +;; ;; Disable SSH feature when not available ;DISABLE_SSH = false ;; ;; Whether to use the builtin SSH server or not. ;START_SSH_SERVER = false ;; -;; Username to use for the builtin SSH server. +;; Expect PROXY protocol header on connections to the built-in SSH server +;SSH_SERVER_USE_PROXY_PROTOCOL = false +;; +;; Username to use for the builtin SSH server. If blank, then it is the value of RUN_USER. ;BUILTIN_SSH_SERVER_USER = %(RUN_USER)s ;; ;; Domain name to be exposed in clone URL @@ -1144,6 +1164,10 @@ ROUTER = console ;; ;; Whether to enable a Service Worker to cache frontend assets ;USE_SERVICE_WORKER = false +;; +;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. +;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). +;ONLY_SHOW_RELEVANT_REPOS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/.gitignore b/docs/.gitignore index 9cd1408bd..271adbb1d 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,3 +2,6 @@ public/ templates/swagger/v1_json.tmpl themes/ resources/ + +# Temporary lock file while building +/.hugo_build.lock diff --git a/docs/config.yaml b/docs/config.yaml index d9544bd30..92e033a90 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -18,7 +18,7 @@ params: description: Git with a cup of tea author: The Gitea Authors website: https://docs.gitea.io - version: 1.16.9 + version: 1.17.1 minGoVersion: 1.18 goVersion: 1.19 minNodeVersion: 14 diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 37f887d4a..05cedeb63 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -194,6 +194,8 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. - `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page. - `USE_SERVICE_WORKER`: **false**: Whether to enable a Service Worker to cache frontend assets. +- `ONLY_SHOW_RELEVANT_REPOS`: **false** Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. + A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). ### UI - Admin (`ui.admin`) @@ -238,6 +240,10 @@ The following configuration set `Content-Type: application/vnd.android.package-a ## Server (`server`) - `PROTOCOL`: **http**: \[http, https, fcgi, http+unix, fcgi+unix\] +- `USE_PROXY_PROTOCOL`: **false**: Expect PROXY protocol headers on connections +- `PROXY_PROTOCOL_TLS_BRIDGING`: **false**: When protocol is https, expect PROXY protocol headers after TLS negotiation. +- `PROXY_PROTOCOL_HEADER_TIMEOUT`: **5s**: Timeout to wait for PROXY protocol header (set to 0 to have no timeout) +- `PROXY_PROTOCOL_ACCEPT_UNKNOWN`: **false**: Accept PROXY protocol headers with Unknown type. - `DOMAIN`: **localhost**: Domain name of this server. - `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**: Overwrite the automatically generated public URL. @@ -262,12 +268,15 @@ The following configuration set `Content-Type: application/vnd.android.package-a most cases you do not need to change the default value. Alter it only if your SSH server node is not the same as HTTP node. Do not set this variable if `PROTOCOL` is set to `http+unix`. +- `LOCAL_USE_PROXY_PROTOCOL`: **%(USE_PROXY_PROTOCOL)**: When making local connections pass the PROXY protocol header. + This should be set to false if the local connection will go through the proxy. - `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to -1 to disable all timeouts.) - `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections. - `DISABLE_SSH`: **false**: Disable SSH feature when it's not available. - `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server. +- `SSH_SERVER_USE_PROXY_PROTOCOL`: **false**: Expect PROXY protocol header on connections to the built-in SSH Server. - `BUILTIN_SSH_SERVER_USER`: **%(RUN_USER)s**: Username to use for the built-in SSH Server. - `SSH_USER`: **%(BUILTIN_SSH_SERVER_USER)**: SSH username displayed in clone URLs. This is only for people who configure the SSH server themselves; in most cases, you want to leave this blank and modify the `BUILTIN_SSH_SERVER_USER`. - `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL. @@ -313,6 +322,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `LFS_LOCKS_PAGING_NUM`: **50**: Maximum number of LFS Locks returned per page. - `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, allows redirecting http requests on `PORT_TO_REDIRECT` to the https port Gitea listens on. +- `REDIRECTOR_USE_PROXY_PROTOCOL`: **%(USE_PROXY_PROTOCOL)**: expect PROXY protocol header on connections to https redirector. - `PORT_TO_REDIRECT`: **80**: Port for the http redirection service to listen on. Used when `REDIRECT_OTHER_PORT` is true. - `SSL_MIN_VERSION`: **TLSv1.2**: Set the minimum version of ssl support. - `SSL_MAX_VERSION`: **\**: Set the maximum version of ssl support. diff --git a/docs/content/doc/developers/api-usage.en-us.md b/docs/content/doc/developers/api-usage.en-us.md index 1ff912353..a7b87f8f0 100644 --- a/docs/content/doc/developers/api-usage.en-us.md +++ b/docs/content/doc/developers/api-usage.en-us.md @@ -49,7 +49,7 @@ Note that `/users/:name/tokens` is a special endpoint and requires you to authenticate using `BasicAuth` and a password, as follows: ```sh -$ curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"test"}' -u username:password https://gitea.your.host/api/v1/users//tokens +$ curl -H "Content-Type: application/json" -d '{"name":"test"}' -u username:password https://gitea.your.host/api/v1/users//tokens {"id":1,"name":"test","sha1":"9fcb1158165773dd010fca5f0cf7174316c3e37d","token_last_eight":"16c3e37d"} ``` @@ -58,7 +58,7 @@ plain-text. It will not be displayed when listing tokens with a `GET` request; e.g. ```sh -$ curl --request GET --url https://yourusername:password@gitea.your.host/api/v1/users//tokens +$ curl --url https://yourusername:password@gitea.your.host/api/v1/users//tokens [{"name":"test","sha1":"","token_last_eight:"........":},{"name":"dev","sha1":"","token_last_eight":"........"}] ``` @@ -70,7 +70,7 @@ is where you'd place the code from your authenticator. Here is how the request would look like in curl: ```sh -$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens +$ curl -H "X-Gitea-OTP: 123456" --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens ``` You can also create an API key token via your Gitea installation's web @@ -96,7 +96,7 @@ Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675 In a `curl` command, for instance, this would look like: ```sh -curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \ +curl "http://localhost:4000/api/v1/repos/test1/test1/issues" \ -H "accept: application/json" \ -H "Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675" \ -H "Content-Type: application/json" -d "{ \"body\": \"testing\", \"title\": \"test 20\"}" -i diff --git a/docs/content/doc/developers/api-usage.zh-cn.md b/docs/content/doc/developers/api-usage.zh-cn.md index 17a1cf110..c99836111 100644 --- a/docs/content/doc/developers/api-usage.zh-cn.md +++ b/docs/content/doc/developers/api-usage.zh-cn.md @@ -46,7 +46,7 @@ Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675 ไปฅ `curl` ๅ‘ฝไปคไธบไพ‹๏ผŒๅฎƒไผšไปฅๅฆ‚ไธ‹ๅฝขๅผๆบๅธฆๅœจ่ฏทๆฑ‚ไธญ๏ผš ``` -curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \ +curl "http://localhost:4000/api/v1/repos/test1/test1/issues" \ -H "accept: application/json" \ -H "Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675" \ -H "Content-Type: application/json" -d "{ \"body\": \"testing\", \"title\": \"test 20\"}" -i @@ -62,7 +62,7 @@ curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \ ### ไฝฟ็”จ Basic authentication ่ฎค่ฏ๏ผš ``` -$ curl --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens +$ curl --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens [{"name":"test","sha1":"..."},{"name":"dev","sha1":"..."}] ``` diff --git a/docs/content/doc/developers/guidelines-backend.md b/docs/content/doc/developers/guidelines-backend.md index 4280aa80f..b680d73c8 100644 --- a/docs/content/doc/developers/guidelines-backend.md +++ b/docs/content/doc/developers/guidelines-backend.md @@ -33,7 +33,9 @@ To maintain understandable code and avoid circular dependencies it is important - `build`: Scripts to help build Gitea. - `cmd`: All Gitea actual sub commands includes web, doctor, serv, hooks, admin and etc. `web` will start the web service. `serv` and `hooks` will be invoked by Git or OpenSSH. Other sub commands could help to maintain Gitea. -- `integrations`: Integration tests +- `tests`: Common test utility functions + - `tests/integration`: Integration tests, to test back-end regressions + - `tests/e2e`: E2e tests, to test test front-end <> back-end compatibility and visual regressions. - `models`: Contains the data structures used by xorm to construct database tables. It also contains functions to query and update the database. Dependencies to other Gitea code should be avoided. You can make exceptions in cases such as logging. - `models/db`: Basic database operations. All other `models/xxx` packages should depend on this package. The `GetEngine` function should only be invoked from `models/`. - `models/fixtures`: Sample data used in unit tests and integration tests. One `yml` file means one table which will be loaded into database when beginning the tests. diff --git a/docs/content/doc/developers/hacking-on-gitea.en-us.md b/docs/content/doc/developers/hacking-on-gitea.en-us.md index abefb1ca9..361ab530f 100644 --- a/docs/content/doc/developers/hacking-on-gitea.en-us.md +++ b/docs/content/doc/developers/hacking-on-gitea.en-us.md @@ -309,7 +309,7 @@ will run the integration tests in an SQLite environment. Integration tests require `git lfs` to be installed. Other database tests are available but may need adjustment to the local environment. -Take a look at [`integrations/README.md`](https://github.com/go-gitea/gitea/blob/main/integrations/README.md) +Take a look at [`tests/integration/README.md`](https://github.com/go-gitea/gitea/blob/main/tests/integration/README.md) for more information and how to run a single test. ### Testing for a PR diff --git a/docs/content/doc/features/comparison.en-us.md b/docs/content/doc/features/comparison.en-us.md index db13c87d5..3c2a3f916 100644 --- a/docs/content/doc/features/comparison.en-us.md +++ b/docs/content/doc/features/comparison.en-us.md @@ -35,24 +35,24 @@ _Symbols used in table:_ | Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE | | ----------------------------------- | ---------------------------------------------------| ---- | --------- | --------- | --------- | -------------- | ------------ | -| Open source and free | โœ“ | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ“ | -| Low resource usage (RAM/CPU) | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | -| Multiple database support | โœ“ | โœ“ | โœ˜ | โ„ | โ„ | โœ“ | โœ“ | -| Multiple OS support | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ“ | -| Easy upgrade process | โœ“ | โœ“ | โœ˜ | โœ“ | โœ“ | โœ˜ | โœ“ | -| Markdown support | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | -| Orgmode support | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ˜ | ? | -| CSV support | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ“ | ? | -| Third-party render tool support | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ“ | ? | -| Static Git-powered pages | [โœ˜](https://github.com/go-gitea/gitea/issues/302) | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | -| Integrated Git-powered wiki | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ (cloud only) | โœ˜ | -| Deploy Tokens | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | -| Repository Tokens with write rights | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | -| Built-in Package/Container Registry | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | -| External git mirroring | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ“ | -| WebAuthn (2FA) | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ“ | ? | -| Built-in CI/CD | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | -| Subgroups: groups within groups | โœ˜ | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ˜ | โœ“ | +| Open source and free | โœ“ | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ“ | +| Low resource usage (RAM/CPU) | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | +| Multiple database support | โœ“ | โœ“ | โœ˜ | โ„ | โ„ | โœ“ | โœ“ | +| Multiple OS support | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ“ | +| Easy upgrade process | โœ“ | โœ“ | โœ˜ | โœ“ | โœ“ | โœ˜ | โœ“ | +| Markdown support | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | +| Orgmode support | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ˜ | ? | +| CSV support | โœ“ | โœ˜ | โœ“ | โœ˜ | โœ˜ | โœ“ | ? | +| Third-party render tool support | โœ“ | โœ˜ | โœ˜ | โœ˜ | โœ˜ | โœ“ | ? | +| Static Git-powered pages | [โœ˜](https://github.com/go-gitea/gitea/issues/302) | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | +| Integrated Git-powered wiki | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ (cloud only) | โœ˜ | +| Deploy Tokens | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | +| Repository Tokens with write rights | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ“ | โœ“ | +| Built-in Package/Container Registry | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | +| External git mirroring | โœ“ | โœ“ | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ“ | +| WebAuthn (2FA) | โœ“ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ“ | ? | +| Built-in CI/CD | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ“ | โœ˜ | โœ˜ | +| Subgroups: groups within groups | [โœ˜](https://github.com/go-gitea/gitea/issues/1872) | โœ˜ | โœ˜ | โœ“ | โœ“ | โœ˜ | โœ“ | ## Code management diff --git a/docs/content/doc/installation/on-kubernetes.zh-cn.md b/docs/content/doc/installation/on-kubernetes.zh-cn.md new file mode 100644 index 000000000..b1556a26f --- /dev/null +++ b/docs/content/doc/installation/on-kubernetes.zh-cn.md @@ -0,0 +1,82 @@ +--- +date: "2020-03-19T19:27:00+02:00" +title: "ๅœจ Kubernetes ๅฎ‰่ฃ… Gitea" +slug: "install-on-kubernetes" +weight: 10 +toc: false +draft: false +menu: + sidebar: + parent: "installation" + name: "Kubernetes" + weight: 50 + identifier: "install-on-kubernetes" +--- + +# ไฝฟ็”จ Helm ๅœจ Kubernetes ไบ‘ๅŽŸ็”Ÿ็Žฏๅขƒไธญๅฎ‰่ฃ… Gitea + +Gitea ๅทฒ็ปๆไพ›ไบ†ไพฟไบŽๅœจ Kubernetes ไบ‘ๅŽŸ็”Ÿ็Žฏๅขƒไธญๅฎ‰่ฃ…ๆ‰€้œ€็š„ Helm Chart + +้ป˜่ฎคๅฎ‰่ฃ…ๆŒ‡ไปคไธบ๏ผš + +```bash +helm repo add gitea https://dl.gitea.io/charts +helm repo update +helm install gitea gitea/gitea +``` + +ๅฆ‚ๆžœ้‡‡็”จ้ป˜่ฎคๅฎ‰่ฃ…ๆŒ‡ไปค๏ผŒHelm ไผš้ƒจ็ฝฒๅ•ๅฎžไพ‹็š„ Gitea, PostgreSQL, Memcachedใ€‚่‹ฅๆ‚จๆƒณๅฎž็Žฐ่‡ชๅฎšไน‰ๅฎ‰่ฃ…๏ผˆๅŒ…ๆ‹ฌ้…็ฝฎ Gitea ้›†็พคใ€NGINX Ingressใ€MySQLใ€MariaDBใ€ๆŒไน…ๅญ˜ๅ‚จ็ญ‰๏ผ‰๏ผŒ่ฏทๅ‰ๅพ€้˜…่ฏป๏ผš[Gitea Helm Chart](https://gitea.com/gitea/helm-chart/) + +ๆ‚จไนŸๅฏไปฅ้€š่ฟ‡ `helm show` ๅ‘ฝไปคๅฏผๅ‡บ `README.md` ๅ’Œ้…็ฝฎๆ–‡ไปถ `values.yaml` ่ฟ›่กŒๅญฆไน ๅ’Œ็ผ–่พ‘๏ผŒไพ‹ๅฆ‚๏ผš + +```bash +helm show values gitea/gitea > values.yaml +helm show readme gitea/gitea > README.md + +# ไฝฟ็”จ่‡ชๅฎšไน‰็š„้…็ฝฎๆ–‡ไปถ values.yaml +helm install gitea -f values.yaml gitea/gitea +``` + +## ่ฟ่กŒ็Šถๅ†ตๆฃ€ๆŸฅๆŽฅๅฃ + +Gitea ้™„ๅธฆไบ†ไธ€ไธช่ฟ่กŒ็Šถๅ†ตๆฃ€ๆŸฅๆŽฅๅฃ `/api/healthz`๏ผŒไฝ ๅฏไปฅๅƒ่ฟ™ๆ ทๅœจ Kubernetes ไธญ้…็ฝฎๅฎƒ๏ผš + +```yaml + livenessProbe: + httpGet: + path: /api/healthz + port: http + initialDelaySeconds: 200 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 10 +``` + +ๆˆๅŠŸ็š„่ฟ่กŒ็Šถๅ†ตๆฃ€ๆŸฅๅ“ๅบ”ไปฃ็ ไธบ HTTP `200`๏ผŒไธ‹้ขๆ˜ฏ็คบไพ‹๏ผš + +``` +HTTP/1.1 200 OK + + +{ + "status": "pass", + "description": "Gitea: Git with a cup of tea", + "checks": { + "cache:ping": [ + { + "status": "pass", + "time": "2022-02-19T09:16:08Z" + } + ], + "database:ping": [ + { + "status": "pass", + "time": "2022-02-19T09:16:08Z" + } + ] + } +} +``` + +ๆœ‰ๅ…ณๆ›ดๅคšไฟกๆฏ๏ผŒ่ฏทๅ‚่€ƒ Kubernetes ๆ–‡ๆกฃ [้…็ฝฎๅญ˜ๆดปใ€ๅฐฑ็ปชๅ’ŒๅฏๅŠจๆŽขๆต‹ๅ™จ](https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) diff --git a/docs/content/doc/installation/windows-service.en-us.md b/docs/content/doc/installation/windows-service.en-us.md index 079577152..0db860dfb 100644 --- a/docs/content/doc/installation/windows-service.en-us.md +++ b/docs/content/doc/installation/windows-service.en-us.md @@ -49,6 +49,16 @@ Open "Windows Services", search for the service named "gitea", right-click it an "Run". If everything is OK, Gitea will be reachable on `http://localhost:3000` (or the port that was configured). +## Adding startup dependancies + +To add a startup dependancy to the Gitea Windows service (eg Mysql, Mariadb), as an Administrator, then run the following command: + +``` +sc.exe config gitea depend= mariadb +``` + +This will ensure that when the Windows machine restarts, the automatic starting of Gitea is postponed until the database is ready and thus mitigate failed startups. + ## Unregister as a service To unregister Gitea as a service, open a command prompt (cmd) as an Administrator and run: diff --git a/docs/content/doc/packages/overview.en-us.md b/docs/content/doc/packages/overview.en-us.md index 5e03b7101..0abb054b0 100644 --- a/docs/content/doc/packages/overview.en-us.md +++ b/docs/content/doc/packages/overview.en-us.md @@ -37,6 +37,7 @@ The following package managers are currently supported: | [Pub]({{< relref "doc/packages/pub.en-us.md" >}}) | Dart | `dart`, `flutter` | | [PyPI]({{< relref "doc/packages/pypi.en-us.md" >}}) | Python | `pip`, `twine` | | [RubyGems]({{< relref "doc/packages/rubygems.en-us.md" >}}) | Ruby | `gem`, `Bundler` | +| [Vagrant]({{< relref "doc/packages/vagrant.en-us.md" >}}) | - | `vagrant` | **The following paragraphs only apply if Packages are not globally disabled!** diff --git a/docs/content/doc/packages/vagrant.en-us.md b/docs/content/doc/packages/vagrant.en-us.md new file mode 100644 index 000000000..e846de1a2 --- /dev/null +++ b/docs/content/doc/packages/vagrant.en-us.md @@ -0,0 +1,78 @@ +--- +date: "2022-08-23T00:00:00+00:00" +title: "Vagrant Packages Repository" +slug: "packages/vagrant" +draft: false +toc: false +menu: + sidebar: + parent: "packages" + name: "vagrant" + weight: 120 + identifier: "vagrant" +--- + +# Vagrant Packages Repository + +Publish [Vagrant](https://www.vagrantup.com/) packages for your user or organization. + +**Table of Contents** + +{{< toc >}} + +## Requirements + +To work with the Vagrant package registry, you need [Vagrant](https://www.vagrantup.com/downloads) and a tool to make HTTP requests like `curl`. + +## Publish a package + +Publish a Vagrant box by performing a HTTP PUT request to the registry: + +``` +PUT https://gitea.example.com/api/packages/{owner}/vagrant/{package_name}/{package_version}/{provider}.box +``` + +| Parameter | Description | +| ----------------- | ----------- | +| `owner` | The owner of the package. | +| `package_name` | The package name. | +| `package_version` | The package version, semver compatible. | +| `provider` | One of the [supported provider names](https://www.vagrantup.com/docs/providers). | + +Example for uploading a Hyper-V box: + +```shell +curl --user your_username:your_password_or_token \ + --upload-file path/to/your/vagrant.box \ + https://gitea.example.com/api/packages/testuser/vagrant/test_system/1.0.0/hyperv.box +``` + +You cannot publish a box if a box of the same name, version and provider already exists. You must delete the existing package first. + +## Install a package + +To install a box from the package registry, execute the following command: + +```shell +vagrant box add "https://gitea.example.com/api/packages/{owner}/vagrant/{package_name}" +``` + +| Parameter | Description | +| -------------- | ----------- | +| `owner` | The owner of the package. | +| `package_name` | The package name. | + +For example: + +```shell +vagrant box add "https://gitea.example.com/api/packages/testuser/vagrant/test_system" +``` + +This will install the latest version of the package. To add a specific version, use the `--box-version` parameter. +If the registry is private you can pass your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) in the `VAGRANT_CLOUD_TOKEN` environment variable. + +## Supported commands + +``` +vagrant box add +``` diff --git a/docs/content/doc/usage/agit-support.en-us.md b/docs/content/doc/usage/agit-support.en-us.md new file mode 100644 index 000000000..c71be6837 --- /dev/null +++ b/docs/content/doc/usage/agit-support.en-us.md @@ -0,0 +1,47 @@ +--- +date: " 2022-09-01T20:50:42+0000" +title: "Usage: Agit Setup" +slug: "agit-setup" +weight: 12 +toc: false +draft: false +menu: + sidebar: + parent: "usage" + name: "Agit Setup" + weight: 12 + identifier: "agit-setup" +--- + +# Agit Setup + +In Gitea `1.13`, support for [agit](https://git-repo.info/en/2020/03/agit-flow-and-git-repo/) was added. + +## Creating PRs with Agit + +Agit allows to create PRs while pushing code to the remote repo. \ +This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git). \ +The following example illustrates this: + +```shell +git push origin HEAD:refs/for/master +``` + +The command has the following structure: + +- `HEAD`: The target branch +- `refs//`: The target PR type + - `for`: Create a normal PR with `` as the target branch + - `draft`/ `for-review`: Currently ignored silently +- `/`: The target branch to open the PR +- `-o `: Options for the PR + - `title`: The PR title + - `topic`: The branch name the PR should be opened for + - `description`: The PR description + - `force-push`: confirm force update the target branch + +Here's another advanced example for creating a new PR targeting `master` with `topic`, `title`, and `description`: + +```shell +git push origin HEAD:refs/for/master -o topic="Topic of my PR" -o title="Title of the PR" -o description="# The PR Description\nThis can be **any** markdown content.\n- [x] Ok" +``` diff --git a/docs/content/doc/usage/backup-and-restore.en-us.md b/docs/content/doc/usage/backup-and-restore.en-us.md index c9c41c413..cae097082 100644 --- a/docs/content/doc/usage/backup-and-restore.en-us.md +++ b/docs/content/doc/usage/backup-and-restore.en-us.md @@ -62,7 +62,7 @@ The SQL dump created by `gitea dump` uses XORM and Gitea admins may prefer to us # mysql mysqldump -u$USER -p$PASS --database $DATABASE > gitea-db.sql # postgres -pgdump -U $USER $DATABASE > gitea-db.sql +pg_dump -U $USER $DATABASE > gitea-db.sql ``` ### Using Docker (`dump`) diff --git a/docs/content/doc/usage/https-support.md b/docs/content/doc/usage/https-support.md index 783d6d803..7c9024743 100644 --- a/docs/content/doc/usage/https-support.md +++ b/docs/content/doc/usage/https-support.md @@ -72,7 +72,7 @@ ACME_DIRECTORY=https ACME_EMAIL=email@example.com ``` -Minimumg setup using a [smallstep CA](https://github.com/smallstep/certificates), refer to [their tutorial](https://smallstep.com/docs/tutorials/acme-challenge) for more information. +Minimum setup using a [smallstep CA](https://github.com/smallstep/certificates), refer to [their tutorial](https://smallstep.com/docs/tutorials/acme-challenge) for more information. ```ini [server] diff --git a/docs/content/doc/usage/issue-pull-request-templates.en-us.md b/docs/content/doc/usage/issue-pull-request-templates.en-us.md index 38cbfbf8a..f1d577e77 100644 --- a/docs/content/doc/usage/issue-pull-request-templates.en-us.md +++ b/docs/content/doc/usage/issue-pull-request-templates.en-us.md @@ -25,51 +25,53 @@ main branch of the repository so that they can autopopulate the form when users creating issues and pull requests. This will cut down on the initial back and forth of getting some clarifying details. +Additionally, the New Issue page URL can be suffixed with `?title=Issue+Title&body=Issue+Text` and the form will be populated with those strings. Those strings will be used instead of the template if there is one. + +## File names + Possible file names for issue templates: - `ISSUE_TEMPLATE.md` +- `ISSUE_TEMPLATE.yaml` +- `ISSUE_TEMPLATE.yml` - `issue_template.md` +- `issue_template.yaml` +- `issue_template.yml` - `.gitea/ISSUE_TEMPLATE.md` +- `.gitea/ISSUE_TEMPLATE.yaml` +- `.gitea/ISSUE_TEMPLATE.yml` +- `.gitea/issue_template.md` +- `.gitea/issue_template.yaml` - `.gitea/issue_template.md` - `.github/ISSUE_TEMPLATE.md` +- `.github/ISSUE_TEMPLATE.yaml` +- `.github/ISSUE_TEMPLATE.yml` - `.github/issue_template.md` +- `.github/issue_template.yaml` +- `.github/issue_template.yml` Possible file names for PR templates: - `PULL_REQUEST_TEMPLATE.md` +- `PULL_REQUEST_TEMPLATE.yaml` +- `PULL_REQUEST_TEMPLATE.yml` - `pull_request_template.md` +- `pull_request_template.yaml` +- `pull_request_template.yml` - `.gitea/PULL_REQUEST_TEMPLATE.md` +- `.gitea/PULL_REQUEST_TEMPLATE.yaml` +- `.gitea/PULL_REQUEST_TEMPLATE.yml` - `.gitea/pull_request_template.md` +- `.gitea/pull_request_template.yaml` +- `.gitea/pull_request_template.yml` - `.github/PULL_REQUEST_TEMPLATE.md` +- `.github/PULL_REQUEST_TEMPLATE.yaml` +- `.github/PULL_REQUEST_TEMPLATE.yml` - `.github/pull_request_template.md` +- `.github/pull_request_template.yaml` +- `.github/pull_request_template.yml` -Possible file names for PR default merge message templates: - -- `.gitea/default_merge_message/MERGE_TEMPLATE.md` -- `.gitea/default_merge_message/REBASE_TEMPLATE.md` -- `.gitea/default_merge_message/REBASE-MERGE_TEMPLATE.md` -- `.gitea/default_merge_message/SQUASH_TEMPLATE.md` -- `.gitea/default_merge_message/MANUALLY-MERGED_TEMPLATE.md` -- `.gitea/default_merge_message/REBASE-UPDATE-ONLY_TEMPLATE.md` - -You can use the following variables enclosed in `${}` inside these templates which follow [os.Expand](https://pkg.go.dev/os#Expand) syntax: - -- BaseRepoOwnerName: Base repository owner name of this pull request -- BaseRepoName: Base repository name of this pull request -- BaseBranch: Base repository target branch name of this pull request -- HeadRepoOwnerName: Head repository owner name of this pull request -- HeadRepoName: Head repository name of this pull request -- HeadBranch: Head repository branch name of this pull request -- PullRequestTitle: Pull request's title -- PullRequestDescription: Pull request's description -- PullRequestPosterName: Pull request's poster name -- PullRequestIndex: Pull request's index number -- PullRequestReference: Pull request's reference char with index number. i.e. #1, !2 -- ClosingIssues: return a string contains all issues which will be closed by this pull request i.e. `close #1, close #2` - -Additionally, the New Issue page URL can be suffixed with `?title=Issue+Title&body=Issue+Text` and the form will be populated with those strings. Those strings will be used instead of the template if there is one. - -## Issue Template Directory +## Directory names Alternatively, users can create multiple issue templates inside a special directory and allow users to choose one that more specifically addresses their problem. @@ -85,7 +87,9 @@ Possible directory names for issue templates: - `.gitlab/ISSUE_TEMPLATE` - `.gitlab/issue_template` -Inside the directory can be multiple markdown (`.md`) issue templates of the form +Inside the directory can be multiple markdown (`.md`) or yaml (`.yaml`/`.yml`) issue templates of the form. + +## Syntax for markdown template ```md --- @@ -108,3 +112,158 @@ In the above example, when a user is presented with the list of issues they can `This template is for testing!`. When submitting an issue with the above example, the issue title would be pre-populated with `[TEST] ` while the issue body would be pre-populated with `This is the template!`. The issue would also be assigned two labels, `bug` and `help needed`, and the issue will have a reference to `main`. + +## Syntax for yaml template + +This example YAML configuration file defines an issue form using several inputs to report a bug. + +```yaml +name: Bug Report +about: File a bug report +title: "[Bug]: " +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: input + id: contact + attributes: + label: Contact Details + description: How can we get in touch with you if we need more info? + placeholder: ex. email@example.com + validations: + required: false + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! + value: "A bug happened!" + validations: + required: true + - type: dropdown + id: version + attributes: + label: Version + description: What version of our software are you running? + options: + - 1.0.2 (Default) + - 1.0.3 (Edge) + validations: + required: true + - type: dropdown + id: browsers + attributes: + label: What browsers are you seeing the problem on? + multiple: true + options: + - Firefox + - Chrome + - Safari + - Microsoft Edge + - type: textarea + id: logs + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com) + options: + - label: I agree to follow this project's Code of Conduct + required: true +``` + +### Markdown + +You can use a `markdown` element to display Markdown in your form that provides extra context to the user, but is not submitted. + +Attributes: + +| Key | Description | Required | Type | Default | Valid values | +|-------|--------------------------------------------------------------|----------|--------|---------|--------------| +| value | The text that is rendered. Markdown formatting is supported. | Required | String | - | - | + +### Textarea + +You can use a `textarea` element to add a multi-line text field to your form. Contributors can also attach files in `textarea` fields. + +Attributes: + +| Key | Description | Required | Type | Default | Valid values | +|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|--------|--------------|---------------------------| +| label | A brief description of the expected user input, which is also displayed in the form. | Required | String | - | - | +| description | A description of the text area to provide context or guidance, which is displayed in the form. | Optional | String | Empty String | - | +| placeholder | A semi-opaque placeholder that renders in the text area when empty. | Optional | String | Empty String | - | +| value | Text that is pre-filled in the text area. | Optional | String | - | - | +| render | If a value is provided, submitted text will be formatted into a codeblock. When this key is provided, the text area will not expand for file attachments or Markdown editing. | Optional | String | - | Languages known to Gitea. | + +Validations: + +| Key | Description | Required | Type | Default | Valid values | +|----------|------------------------------------------------------|----------|---------|---------|--------------| +| required | Prevents form submission until element is completed. | Optional | Boolean | false | - | + +### Input + +You can use an `input` element to add a single-line text field to your form. + +Attributes: + +| Key | Description | Required | Type | Default | Valid values | +|-------------|--------------------------------------------------------------------------------------------|----------|--------|--------------|--------------| +| label | A brief description of the expected user input, which is also displayed in the form. | Required | String | - | - | +| description | A description of the field to provide context or guidance, which is displayed in the form. | Optional | String | Empty String | - | +| placeholder | A semi-transparent placeholder that renders in the field when empty. | Optional | String | Empty String | - | +| value | Text that is pre-filled in the field. | Optional | String | - | - | + +Validations: + +| Key | Description | Required | Type | Default | Valid values | +|-----------|--------------------------------------------------------------------------------------------------|----------|---------|---------|--------------------------------------------------------------------------| +| required | Prevents form submission until element is completed. | Optional | Boolean | false | - | +| is_number | Prevents form submission until element is filled with a number. | Optional | Boolean | false | - | +| regex | Prevents form submission until element is filled with a value that match the regular expression. | Optional | String | - | a [regular expression](https://en.wikipedia.org/wiki/Regular_expression) | + +### Dropdown + +You can use a `dropdown` element to add a dropdown menu in your form. + +Attributes: + +| Key | Description | Required | Type | Default | Valid values | +|-------------|-----------------------------------------------------------------------------------------------------|----------|--------------|--------------|--------------| +| label | A brief description of the expected user input, which is displayed in the form. | Required | String | - | - | +| description | A description of the dropdown to provide extra context or guidance, which is displayed in the form. | Optional | String | Empty String | - | +| multiple | Determines if the user can select more than one option. | Optional | Boolean | false | - | +| options | An array of options the user can choose from. Cannot be empty and all choices must be distinct. | Required | String array | - | - | + +Validations: + +| Key | Description | Required | Type | Default | Valid values | +|----------|------------------------------------------------------|----------|---------|---------|--------------| +| required | Prevents form submission until element is completed. | Optional | Boolean | false | - | + +### Checkboxes + +You can use the `checkboxes` element to add a set of checkboxes to your form. + +Attributes: + +| Key | Description | Required | Type | Default | Valid values | +|-------------|-------------------------------------------------------------------------------------------------------|----------|--------|--------------|--------------| +| label | A brief description of the expected user input, which is displayed in the form. | Required | String | - | - | +| description | A description of the set of checkboxes, which is displayed in the form. Supports Markdown formatting. | Optional | String | Empty String | - | +| options | An array of checkboxes that the user can select. For syntax, see below. | Required | Array | - | - | + +For each value in the options array, you can set the following keys. + +| Key | Description | Required | Type | Default | Options | +|----------|------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|---------|---------| +| label | The identifier for the option, which is displayed in the form. Markdown is supported for bold or italic text formatting, and hyperlinks. | Required | String | - | - | +| required | Prevents form submission until element is completed. | Optional | Boolean | false | - | diff --git a/docs/content/doc/usage/merge-message-templates.en-us.md b/docs/content/doc/usage/merge-message-templates.en-us.md new file mode 100644 index 000000000..c30ac1bfe --- /dev/null +++ b/docs/content/doc/usage/merge-message-templates.en-us.md @@ -0,0 +1,48 @@ +--- +date: "2022-08-31T17:35:40+08:00" +title: "Usage: Merge Message templates" +slug: "merge-message-templates" +weight: 15 +toc: false +draft: false +menu: + sidebar: + parent: "usage" + name: "Merge Message templates" + weight: 15 + identifier: "merge-message-templates" +--- + +# Merge Message templates + +**Table of Contents** + +{{< toc >}} + +## File names + +Possible file names for PR default merge message templates: + +- `.gitea/default_merge_message/MERGE_TEMPLATE.md` +- `.gitea/default_merge_message/REBASE_TEMPLATE.md` +- `.gitea/default_merge_message/REBASE-MERGE_TEMPLATE.md` +- `.gitea/default_merge_message/SQUASH_TEMPLATE.md` +- `.gitea/default_merge_message/MANUALLY-MERGED_TEMPLATE.md` +- `.gitea/default_merge_message/REBASE-UPDATE-ONLY_TEMPLATE.md` + +## Variables + +You can use the following variables enclosed in `${}` inside these templates which follow [os.Expand](https://pkg.go.dev/os#Expand) syntax: + +- BaseRepoOwnerName: Base repository owner name of this pull request +- BaseRepoName: Base repository name of this pull request +- BaseBranch: Base repository target branch name of this pull request +- HeadRepoOwnerName: Head repository owner name of this pull request +- HeadRepoName: Head repository name of this pull request +- HeadBranch: Head repository branch name of this pull request +- PullRequestTitle: Pull request's title +- PullRequestDescription: Pull request's description +- PullRequestPosterName: Pull request's poster name +- PullRequestIndex: Pull request's index number +- PullRequestReference: Pull request's reference char with index number. i.e. #1, !2 +- ClosingIssues: return a string contains all issues which will be closed by this pull request i.e. `close #1, close #2` diff --git a/go.mod b/go.mod index 218a6e380..45ad786db 100644 --- a/go.mod +++ b/go.mod @@ -5,30 +5,32 @@ go 1.18 require ( code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b code.gitea.io/sdk/gitea v0.15.1 - codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 + codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb gitea.com/go-chi/cache v0.2.0 gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5 gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 + gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7 github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.8.0 github.com/alecthomas/chroma v0.10.0 github.com/blevesearch/bleve/v2 v2.3.2 - github.com/buildkite/terminal-to-html/v3 v3.6.1 - github.com/caddyserver/certmagic v0.16.1 + github.com/buildkite/terminal-to-html/v3 v3.7.0 + github.com/caddyserver/certmagic v0.17.0 github.com/chi-middleware/proxy v1.1.1 - github.com/denisenkom/go-mssqldb v0.12.0 + github.com/denisenkom/go-mssqldb v0.12.2 github.com/djherbis/buffer v1.2.0 github.com/djherbis/nio/v3 v3.0.1 - github.com/duo-labs/webauthn v0.0.0-20220330035159-03696f3d4499 + github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5 github.com/dustin/go-humanize v1.0.0 - github.com/editorconfig/editorconfig-core-go/v2 v2.4.4 + github.com/editorconfig/editorconfig-core-go/v2 v2.4.5 github.com/emirpasic/gods v1.18.1 github.com/ethantkoenig/rupture v1.0.1 - github.com/felixge/fgprof v0.9.2 - github.com/gliderlabs/ssh v0.3.4 + github.com/felixge/fgprof v0.9.3 + github.com/fsnotify/fsnotify v1.5.4 + github.com/gliderlabs/ssh v0.3.5 github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d github.com/go-chi/chi/v5 v5.0.7 @@ -36,19 +38,19 @@ require ( github.com/go-enry/go-enry/v2 v2.8.2 github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-git/go-billy/v5 v5.3.1 - github.com/go-git/go-git/v5 v5.4.3-0.20210630082519-b4368b2a2ca4 - github.com/go-ldap/ldap/v3 v3.4.3 + github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf + github.com/go-ldap/ldap/v3 v3.4.4 github.com/go-redis/redis/v8 v8.11.5 github.com/go-sql-driver/mysql v1.6.0 - github.com/go-swagger/go-swagger v0.29.0 - github.com/go-testfixtures/testfixtures/v3 v3.6.1 + github.com/go-swagger/go-swagger v0.30.0 + github.com/go-testfixtures/testfixtures/v3 v3.8.1 github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v4 v4.4.1 + github.com/golang-jwt/jwt/v4 v4.4.2 github.com/google/go-github/v45 v45.0.0 - github.com/google/pprof v0.0.0-20220509035851-59ca7ad80af3 + github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 github.com/google/uuid v1.3.0 github.com/gorilla/feeds v1.1.1 github.com/gorilla/sessions v1.2.1 @@ -59,49 +61,48 @@ require ( github.com/json-iterator/go v1.1.12 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 - github.com/klauspost/compress v1.15.3 - github.com/klauspost/cpuid/v2 v2.0.12 - github.com/lib/pq v1.10.5 - github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 - github.com/markbates/goth v1.72.0 - github.com/mattn/go-isatty v0.0.14 - github.com/mattn/go-sqlite3 v1.14.12 + github.com/klauspost/compress v1.15.9 + github.com/klauspost/cpuid/v2 v2.1.1 + github.com/lib/pq v1.10.6 + github.com/markbates/goth v1.73.0 + github.com/mattn/go-isatty v0.0.16 + github.com/mattn/go-sqlite3 v1.14.13 github.com/mholt/archiver/v3 v3.5.1 github.com/microcosm-cc/bluemonday v1.0.19 - github.com/minio/minio-go/v7 v7.0.26 + github.com/minio/minio-go/v7 v7.0.35 github.com/msteinert/pam v1.0.0 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 - github.com/niklasfasching/go-org v1.6.2 + github.com/niklasfasching/go-org v1.6.5 github.com/oliamb/cutter v0.2.2 github.com/olivere/elastic/v7 v7.0.32 github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.3.0 - github.com/prometheus/client_golang v1.12.1 + github.com/prometheus/client_golang v1.13.0 github.com/quasoft/websspi v1.1.2 github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 github.com/sergi/go-diff v1.2.0 github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 - github.com/unrolled/render v1.4.1 + github.com/unrolled/render v1.5.0 github.com/urfave/cli v1.22.9 github.com/valyala/fastjson v1.6.3 - github.com/xanzy/go-gitlab v0.64.0 + github.com/xanzy/go-gitlab v0.73.1 github.com/yohcop/openid-go v1.0.0 github.com/yuin/goldmark v1.4.13 github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594 github.com/yuin/goldmark-meta v1.1.0 go.jolheiser.com/hcaptcha v0.0.4 go.jolheiser.com/pwn v0.0.3 - golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 - golang.org/x/net v0.0.0-20220630215102-69896b714898 - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a + golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 + golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b + golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 + golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 golang.org/x/text v0.3.7 - golang.org/x/tools v0.1.10 + golang.org/x/tools v0.1.12 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df - gopkg.in/ini.v1 v1.66.4 + gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v2 v2.4.0 mvdan.cc/xurls/v2 v2.4.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 @@ -110,13 +111,14 @@ require ( ) require ( - cloud.google.com/go v0.99.0 // indirect + cloud.google.com/go/compute v1.7.0 // indirect git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect - github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e // indirect + github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect github.com/RoaringBitmap/roaring v0.9.4 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/andybalholm/brotli v1.0.4 // indirect @@ -146,6 +148,7 @@ require ( github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cloudflare/cfssl v1.6.1 // indirect + github.com/cloudflare/circl v1.2.0 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect github.com/coreos/go-semver v0.3.0 // indirect @@ -156,35 +159,33 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/dlclark/regexp2 v1.4.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect - github.com/envoyproxy/go-control-plane v0.10.1 // indirect + github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fullstorydev/grpcurl v1.8.1 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-openapi/analysis v0.21.2 // indirect - github.com/go-openapi/errors v0.20.2 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/loads v0.21.0 // indirect - github.com/go-openapi/runtime v0.21.1 // indirect - github.com/go-openapi/spec v0.20.4 // indirect - github.com/go-openapi/strfmt v0.21.1 // indirect - github.com/go-openapi/swag v0.19.15 // indirect - github.com/go-openapi/validate v0.20.3 // indirect - github.com/go-stack/stack v1.8.1 // indirect - github.com/goccy/go-json v0.9.7 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/runtime v0.24.1 // indirect + github.com/go-openapi/spec v0.20.7 // indirect + github.com/go-openapi/strfmt v0.21.3 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.0 // indirect + github.com/goccy/go-json v0.9.11 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect - github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -203,7 +204,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/imdario/mergo v0.3.12 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect @@ -215,17 +216,18 @@ require ( github.com/kr/pretty v0.3.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/libdns/libdns v0.2.1 // indirect - github.com/magiconair/properties v1.8.5 // indirect + github.com/magiconair/properties v1.8.6 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/markbates/going v1.0.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/mholt/acmez v1.0.2 // indirect - github.com/miekg/dns v1.1.48 // indirect + github.com/mholt/acmez v1.0.4 // indirect + github.com/miekg/dns v1.1.50 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect @@ -233,68 +235,67 @@ require ( github.com/nwaples/rardecode v1.1.3 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect - github.com/pierrec/lz4/v4 v4.1.14 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/rivo/uniseg v0.3.4 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/xid v1.4.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/shopspring/decimal v1.2.0 // indirect github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/soheilhy/cmux v0.1.5 // indirect - github.com/spf13/afero v1.8.0 // indirect - github.com/spf13/cast v1.4.1 // indirect - github.com/spf13/cobra v1.3.0 // indirect + github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.10.1 // indirect + github.com/spf13/viper v1.12.0 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect - github.com/subosito/gotenv v1.2.0 // indirect + github.com/subosito/gotenv v1.3.0 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/toqueteos/webbrowser v1.2.0 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xanzy/ssh-agent v0.3.1 // indirect + github.com/xanzy/ssh-agent v0.3.2 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.etcd.io/etcd/api/v3 v3.5.1 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.1 // indirect - go.etcd.io/etcd/client/v2 v2.305.1 // indirect - go.etcd.io/etcd/client/v3 v3.5.0-alpha.0 // indirect + go.etcd.io/etcd/api/v3 v3.5.4 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect + go.etcd.io/etcd/client/v2 v2.305.4 // indirect + go.etcd.io/etcd/client/v3 v3.5.4 // indirect go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0 // indirect go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0 // indirect go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0 // indirect go.etcd.io/etcd/server/v3 v3.5.0-alpha.0 // indirect go.etcd.io/etcd/tests/v3 v3.5.0-alpha.0 // indirect go.etcd.io/etcd/v3 v3.5.0-alpha.0 // indirect - go.mongodb.org/mongo-driver v1.8.2 // indirect - go.uber.org/atomic v1.9.0 // indirect + go.mongodb.org/mongo-driver v1.10.1 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.21.0 // indirect - golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + go.uber.org/zap v1.23.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect - google.golang.org/grpc v1.43.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect + google.golang.org/grpc v1.47.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.2.0 // indirect ) replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 -replace github.com/markbates/goth v1.68.0 => github.com/zeripath/goth v1.68.1-0.20220109111530-754359885dce - replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 replace github.com/satori/go.uuid v1.2.0 => github.com/gofrs/uuid v4.2.0+incompatible diff --git a/go.sum b/go.sum index d42a4ebd9..1f548eb94 100644 --- a/go.sum +++ b/go.sum @@ -32,19 +32,26 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD 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.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= 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/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= 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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= 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= @@ -56,14 +63,15 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl 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= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b h1:uv9a8eGSdQ8Dr4HyUcuHFfDsk/QuwO+wf+Y99RYdxY0= code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= -codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 h1:PCW4i+gnQ9XxF8V+nBch3KWdGe4MiP3xXUCA/z0jhHk= -codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= +codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY= +codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= @@ -84,6 +92,8 @@ gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5 h1:J/1i8u40TbcLP/w2w gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5/go.mod h1:hQ9SYHKdOX968wJglb/NMQ+UqpOKwW4L+EYdvkWjHSo= gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 h1:tJQRXgZigkLeeW9LPlps9G9aMoE6LAmqigLA+wxmd1Q= gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8/go.mod h1:fc/pjt5EqNKgqQXYzcas1Z5L5whkZHyOvTA7OzWVJck= +gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:+wWBi6Qfruqu7xJgjOIrKVQGiLUZdpKYCZewJ4clqhw= +gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:VyMQP6ue6MKHM8UsOXfNfuMKD0oSAWZdXVcpHIN2yaY= gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7 h1:Zc3RQWC2xOVglLciQH/ZIC5IqSk3Jn96LflGQLv18Rg= gitea.com/lunny/levelqueue v0.4.2-0.20220729054728-f020868cc2f7/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= @@ -103,26 +113,28 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2 github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ= -github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft7pkxDf6WoUvEZJ/uOKsvtpjLnn8MU= +github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= 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= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.2/go.mod h1:af5vUNlDNkCjOZeSGFgIJxDje9qdjsO6hshx0gTmZt4= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -130,14 +142,11 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 h1:cSHEbLj0GZeHM1mWG84qEnGFojNEQ83W7cwaPRjcwXU= -github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg= +github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= 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/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I= @@ -149,7 +158,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= @@ -160,7 +168,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -181,16 +188,10 @@ github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3st github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -202,7 +203,6 @@ github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -271,11 +271,13 @@ github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/buildkite/terminal-to-html/v3 v3.6.1 h1:yHS+GXsPDXevb67YXjkVwZ4tolDCgPYa9RVOrzHlgGE= -github.com/buildkite/terminal-to-html/v3 v3.6.1/go.mod h1:g0ME1XqbkBSgXR9YmlIHcJIjzaMyWW+HbsG0rPb5puo= +github.com/buildkite/terminal-to-html/v3 v3.7.0 h1:chdLUSpiOj/A4v3dzxyOqixXI6aw7IDA6Dk77FXsvNU= +github.com/buildkite/terminal-to-html/v3 v3.7.0/go.mod h1:g0ME1XqbkBSgXR9YmlIHcJIjzaMyWW+HbsG0rPb5puo= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= -github.com/caddyserver/certmagic v0.16.1 h1:rdSnjcUVJojmL4M0efJ+yHXErrrijS4YYg3FuwRdJkI= -github.com/caddyserver/certmagic v0.16.1/go.mod h1:jKQ5n+ViHAr6DbPwEGLTSM2vDwTO6EvCKBblBRUvvuQ= +github.com/caddyserver/certmagic v0.17.0 h1:AHHvvmv6SNcq0vK5BgCevQqYMV8GNprVk6FWZzx8d+Q= +github.com/caddyserver/certmagic v0.17.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= @@ -296,13 +298,14 @@ github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdi 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/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= github.com/cloudflare/cfssl v1.6.1 h1:aIOUjpeuDJOpWjVJFP2ByplF53OgqG8I1S40Ggdlk3g= github.com/cloudflare/cfssl v1.6.1/go.mod h1:ENhCj4Z17+bY2XikpxVmTHDg/C2IsG2Q0ZBeXpAqhCk= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.2.0 h1:NheeISPSUcYftKlfrLuOo4T62FkmD4t4jviLfFFYaec= +github.com/cloudflare/circl v1.2.0/go.mod h1:Ch2UgYr6ti2KTtlejELlROl0YIYj7SLjAC8M+INXlMk= github.com/cloudflare/redoctober v0.0.0-20201013214028-99c99a8e7544/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= 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= @@ -356,7 +359,6 @@ github.com/couchbase/moss v0.2.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37g github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -372,8 +374,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/denisenkom/go-mssqldb v0.12.2 h1:1OcPn5GBIobjWNd+8yjfHNIaFX14B1pWI3F9HZy5KXw= +github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3l5HkEfra2LJ+sk= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -385,16 +387,16 @@ github.com/djherbis/buffer v1.2.0 h1:PH5Dd2ss0C7CRRhQCZ2u7MssF+No9ide8Ye71nPHcrQ github.com/djherbis/buffer v1.2.0/go.mod h1:fjnebbZjCUpPinBRD+TDwXSOeNQ7fPQWLfGQqiAiUyE= github.com/djherbis/nio/v3 v3.0.1 h1:6wxhnuppteMa6RHA4L81Dq7ThkZH8SwnDzXDYy95vB4= github.com/djherbis/nio/v3 v3.0.1/go.mod h1:Ng4h80pbZFMla1yKzm61cF0tqqilXZYrogmWgZxOcmg= -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/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= -github.com/duo-labs/webauthn v0.0.0-20220330035159-03696f3d4499 h1:jaQHuGKk9NVcfu9VbA7ygslr/7utxdYs47i4osBhZP8= -github.com/duo-labs/webauthn v0.0.0-20220330035159-03696f3d4499/go.mod h1:UMk1JMDgQDcdI2vQz+WJOIUTSjIq07qSepAVgc93rUc= +github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5 h1:BaeJtFDlto/NjX9t730OebRRJf2P+t9YEDz3ur18824= +github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5/go.mod h1:Jcj7rFNlTknb18v9jpSA58BveX2LDhXqaoy+6YV1N9g= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -402,8 +404,8 @@ github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72/go.mod h1:11Gm+ccJ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/editorconfig/editorconfig-core-go/v2 v2.4.4 h1:FclmQqjEE8TqTFe6OGhaZY7MmbWVp9dBvv9vZkeC4Hk= -github.com/editorconfig/editorconfig-core-go/v2 v2.4.4/go.mod h1:mz3wjBRdp75EfR6lp9qLmqyKp76AlT9I2Z13nALZeQs= +github.com/editorconfig/editorconfig-core-go/v2 v2.4.5 h1:kTcVMyCvFGQmTk0S5+R7GF+y7wMHkWm4CYS5BwYWN8U= +github.com/editorconfig/editorconfig-core-go/v2 v2.4.5/go.mod h1:rDB5UUleQsOI1HLbojaBmDNR8oUUe31InmNDTVzcDHY= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= @@ -418,8 +420,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m 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/go-control-plane v0.10.1 h1:cgDRLG7bs59Zd+apAWuzLQL95obVYAymNJek76W3mgw= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.1/go.mod h1:txg5va2Qkip90uYoSKH+nkAAmXrb2j3iq4FLwdrCbXQ= @@ -431,12 +433,11 @@ github.com/ethantkoenig/rupture v1.0.1/go.mod h1:Sjqo/nbffZp1pVVXNGhpugIjsWmuS9K github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/fgprof v0.9.2 h1:tAMHtWMyl6E0BimjVbFt7fieU6FpjttsZN7j0wT5blc= -github.com/felixge/fgprof v0.9.2/go.mod h1:+VNi+ZXtHIQ6wIw6bUT8nXQRefQflWECoFyRealT5sg= +github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= @@ -446,9 +447,9 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fullstorydev/grpcurl v1.8.0/go.mod h1:Mn2jWbdMrQGJQ8UD62uNyMumT2acsZUCkZIqFxsQf1o= @@ -460,10 +461,8 @@ github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JY github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/gliderlabs/ssh v0.3.4 h1:+AXBtim7MTKaLVPgvE+3mhewYRawNLTd+jEEz/wExZw= -github.com/gliderlabs/ssh v0.3.4/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-ap/errors v0.0.0-20220618122732-319f41ac54e1 h1:PkPVIQGt76HHFWSeUINXCfYpEnzlSS+AQyuXi7oJ/gM= @@ -486,13 +485,12 @@ github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5Hql github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= -github.com/go-git/go-git/v5 v5.4.3-0.20210630082519-b4368b2a2ca4 h1:1RSUwVK7VjTeA82kcLIqz1EU70QRwFdZUlJW58gP4GY= -github.com/go-git/go-git/v5 v5.4.3-0.20210630082519-b4368b2a2ca4/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= +github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf h1:tmTaR5nN6RJs6G9+tmd3MRBNXSk6YTI9+8nv1WrIKzI= +github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf/go.mod h1:cGzI9Lmtnh5wmJ5NjO/Cr3d6Iljyy588mEFUKs5vMvw= 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= @@ -501,114 +499,51 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-ldap/ldap/v3 v3.4.3 h1:JCKUtJPIcyOuG7ctGabLKMgIlKnGumD/iGjuWeEruDI= -github.com/go-ldap/ldap/v3 v3.4.3/go.mod h1:7LdHfVt6iIOESVEe3Bs4Jp2sHEKgDeduAhgM1/f9qmo= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-ldap/ldap/v3 v3.4.4 h1:qPjipEpt+qDa6SI/h1fzuGWoRUY+qqQ9sOZq67/PYUs= +github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXgXtJC+aI= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= -github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= -github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= -github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= -github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= -github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= -github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= -github.com/go-openapi/loads v0.21.0 h1:jYtUO4wwP7psAweisP/MDoOpdzsYEESdoPcsWjHDR68= -github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= -github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= -github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.21.1 h1:/KIG00BzA2x2HRStX2tnhbqbQdPcFlkgsYCiNY20FZs= -github.com/go-openapi/runtime v0.21.1/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= -github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= -github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/runtime v0.24.1 h1:Sml5cgQKGYQHF+M7yYSHaH1eOjvTykrddTE/KtQVjqo= +github.com/go-openapi/runtime v0.24.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI= +github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1 h1:G6s2t5V5kGCHLVbSdZ/6lI8Wm4OzoPFkc3/cjAsKQrM= github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= -github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= -github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= -github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= -github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= -github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= -github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw= -github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y= +github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= @@ -620,13 +555,12 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-swagger/go-swagger v0.29.0 h1:z3YoZtLvS1Y8TE/PCat1VypcZxM0IgKLt0NvZxQyNl8= -github.com/go-swagger/go-swagger v0.29.0/go.mod h1:Z4GJzI+bHKKkGB2Ji1rawpi3/ldXX8CkzGIa9HAC5EE= +github.com/go-swagger/go-swagger v0.30.0 h1:HakSyutD7Ek9ndkR8Fxy6WAoQtgu7UcAmZCTa6SzawA= +github.com/go-swagger/go-swagger v0.30.0/go.mod h1:GhZVX/KIBM4VpGp4P7AJOIrlTuBeRVPS+j9kk6rFmfY= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= -github.com/go-testfixtures/testfixtures/v3 v3.6.1 h1:n4Fv95Exp0D05G6l6CAZv22Ck1EJK0pa0TfPqE4ncSs= -github.com/go-testfixtures/testfixtures/v3 v3.6.1/go.mod h1:Bsb2MoHAfHnNsPpSwAjtOs102mqDuM+1u3nE2OCi0N0= +github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU= +github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -656,8 +590,8 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.5/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -675,15 +609,14 @@ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU= -github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= -github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -749,6 +682,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v45 v45.0.0 h1:LU0WBjYidxIVyx7PZeWb+FP4JZJ3Wh3FQgdumnGqiLs= github.com/google/go-github/v45 v45.0.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= @@ -782,8 +716,8 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe 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/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= -github.com/google/pprof v0.0.0-20220509035851-59ca7ad80af3 h1:vFrXU7L2gqtlP/ZGijSpaDIc16ZQrZI4FAuYtpQTyQc= -github.com/google/pprof v0.0.0-20220509035851-59ca7ad80af3/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U= +github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 h1:ykKxL12NZd3JmWZnyqarJGsF73M9Xhtrik/FEtEeFRE= +github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -797,11 +731,16 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= 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/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -850,30 +789,21 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0 h1:bkKf0BeBXcSYa7f5Fyi9gMuQ8gNsxeiNpZjR6VxNZeo= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -887,17 +817,12 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= @@ -909,8 +834,10 @@ github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1: github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -927,8 +854,8 @@ github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= -github.com/jackc/pgconn v1.9.0 h1:gqibKSTJup/ahCsNKyMZAniPuZEfIqfXFc8FOWVYR+Q= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -943,8 +870,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -952,24 +879,20 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= -github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik= github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= -github.com/jackc/pgtype v1.8.0 h1:iFVCcVhYlw0PulYCVoguRGm0SE9guIcPcccnLzHj8bA= github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE= -github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o= -github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= -github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg= github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= -github.com/jackc/pgx/v4 v4.12.0 h1:xiP3TdnkwyslWNp77yE5XAPfxAsU9RMFDe0c1SwN8h4= github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60= +github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -989,12 +912,10 @@ github.com/jhump/protoreflect v1.8.2 h1:k2xE7wcUomeqwY0LDCYA16y4WWfyTcMx5mKhk0d4 github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -1035,16 +956,15 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkGnWpac= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.3 h1:wmfu2iqj9q22SyMINp1uQ8C2/V4M1phJdmH9fG4nba0= -github.com/klauspost/compress v1.15.3/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= @@ -1054,12 +974,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -1080,14 +998,12 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ= -github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY= -github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ= github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ= github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0= github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI= @@ -1097,20 +1013,17 @@ github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc8 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0= github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA= -github.com/markbates/goth v1.72.0 h1:Vm9OE+GsB7FrrvBqKEYsRBiPg4LWJ6DT5zD0XN2Rl4U= -github.com/markbates/goth v1.72.0/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc= +github.com/markbates/goth v1.73.0 h1:X5QUUHLP5puJ4dhoPKkV3PhDIvvQEzsfVxsUmDNSJ28= +github.com/markbates/goth v1.73.0/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= @@ -1120,9 +1033,7 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -1130,11 +1041,10 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -1146,50 +1056,49 @@ github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsO github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= -github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I= +github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mholt/acmez v1.0.2 h1:C8wsEBIUVi6e0DYoxqCcFuXtwc4AWXL/jgcDjF7mjVo= -github.com/mholt/acmez v1.0.2/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM= +github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80= +github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= -github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.26 h1:D0HK+8793etZfRY/vHhDmFaP+vmT41K3K4JV9vmZCBQ= -github.com/minio/minio-go/v7 v7.0.26/go.mod h1:x81+AX5gHSfCSqw7jxRKHvxUXMlE5uKX0Vb75Xk5yYg= +github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU= +github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1223,8 +1132,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/niklasfasching/go-org v1.6.2 h1:kQBIZlfL4oRNApJCrBgaeNBfzxWzP6XlC7/b744Polk= -github.com/niklasfasching/go-org v1.6.2/go.mod h1:wn76Xgu4/KRe43WZhsgZjxYMaloSrl3BSweGV74SwHs= +github.com/niklasfasching/go-org v1.6.5 h1:5YAIqNTdl6lAOb7lD2AyQ1RuFGPVrAKvUexphk8PGbo= +github.com/niklasfasching/go-org v1.6.5/go.mod h1:ybv0eGDnxylFUfFE+ySaQc734j/L3+/ChKZ/h63a2wM= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -1274,22 +1183,22 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= -github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1303,7 +1212,6 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1311,13 +1219,14 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1335,8 +1244,9 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.24.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1345,8 +1255,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pseudomuto/protoc-gen-doc v1.4.1/go.mod h1:exDTOVwqpp30eV/EDPFLZy3Pwr2sn6hBC1WIYH/UbIg= github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= @@ -1357,8 +1268,9 @@ github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqn github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= +github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1367,8 +1279,9 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= @@ -1380,7 +1293,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD 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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE= github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= @@ -1392,6 +1304,7 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= @@ -1407,8 +1320,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -1429,18 +1343,19 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.8.0 h1:5MmtuhAgYeU6qpa7w7bP0dv6MBYuup0vekhSpSkoq60= -github.com/spf13/afero v1.8.0/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1451,9 +1366,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= @@ -1465,6 +1379,7 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1472,10 +1387,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= +github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= @@ -1495,7 +1413,6 @@ github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9r github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ= github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= @@ -1507,8 +1424,8 @@ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -github.com/unrolled/render v1.4.1 h1:VdpMc2YkAOWzbmC/P2yoHhRDXgsaCQHcTJ1KK6SNCA4= -github.com/unrolled/render v1.4.1/go.mod h1:cK4RSTTVdND5j9EYEc0LAMOvdG11JeiKjyjfyZRvV2w= +github.com/unrolled/render v1.5.0 h1:uNTHMvVoI9pyyXfgoDHHycIqFONNY2p4eQR9ty+NsxM= +github.com/unrolled/render v1.5.0/go.mod h1:eLTosBkQqEPEk7pRfkCRApXd++lm++nCsVlFOHpeedw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1520,24 +1437,23 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= -github.com/xanzy/go-gitlab v0.64.0 h1:rMgQdW9S1w3qvNAH2LYpFd2xh7KNLk+JWJd7sorNuTc= -github.com/xanzy/go-gitlab v0.64.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM= +github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI= +github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/xanzy/ssh-agent v0.3.1 h1:AmzO1SSWxw73zxFZPRwaMN1MohDw8UyHnmuxyceTEGo= github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= +github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= +github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -1572,15 +1488,16 @@ 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.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= -go.etcd.io/etcd/api/v3 v3.5.1 h1:v28cktvBq+7vGyJXF8G+rWJmj+1XUmMtqcLnH8hDocM= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1 h1:XIQcHCFSG53bJETYeRJtIxdLv2EWRGxcfzR8lSnTH4E= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= -go.etcd.io/etcd/client/v2 v2.305.1 h1:vtxYCKWA9x31w0WJj7DdqsHFNjhkigdAnziDtkZb/l4= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.etcd.io/etcd/client/v3 v3.5.0-alpha.0 h1:dr1EOILak2pu4Nf5XbRIOCNIBjcz6UmkQd7hHRXwxaM= +go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= +go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0 h1:odMFuQQCg0UmPd7Cyw6TViRYv9ybGuXuki4CusDSzqA= go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0/go.mod h1:YPwSaBciV5G6Gpt435AasAG3ROetZsKNUzibRa/++oo= go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0 h1:3yLUEC0nFCxw/RArImOyRUI4OAFbg4PFpBbAhSNzKNY= @@ -1597,18 +1514,12 @@ go.jolheiser.com/hcaptcha v0.0.4 h1:RrDERcr/Tz/kWyJenjVtI+V09RtLinXxlAemiwN5F+I= go.jolheiser.com/hcaptcha v0.0.4/go.mod h1:aw32WQOxnQZ6E06C0LypCf+sxNxPACyOnq+ZGnrIYho= go.jolheiser.com/pwn v0.0.3 h1:MQowb3QvCL5r5NmHmCPxw93SdjfgJ0q6rAwYn4i1Hjg= go.jolheiser.com/pwn v0.0.3/go.mod h1:/j5Dl8ftNqqJ8Dlx3YTrJV1wIR2lWOTyrNU3Qe7rk6I= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.8.2 h1:8ssUXufb90ujcIvR6MyE1SchaNj0SFxsakiZgxIyrMk= -go.mongodb.org/mongo-driver v1.8.2/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4= +go.mongodb.org/mongo-driver v1.10.1/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1626,8 +1537,8 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1641,11 +1552,11 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1653,25 +1564,21 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1681,15 +1588,16 @@ golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/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-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8= -golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/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= @@ -1727,13 +1635,11 @@ 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.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 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-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1743,7 +1649,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/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-20190320064053-1272bf9dcd53/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= @@ -1755,7 +1660,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1772,7 +1676,6 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ 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-20200602114024-627f9648deb9/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= @@ -1789,7 +1692,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1800,8 +1702,14 @@ golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qx 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-20220630215102-69896b714898 h1:K7wO6V1IrczY9QOQ2WkVpw4JQSwCd52UsxVEirZUfiw= +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-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +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-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1821,10 +1729,13 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ 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-20211005180243-6b3c2da341f1/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-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= +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/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= 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= @@ -1836,8 +1747,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ 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/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1852,7 +1764,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1861,7 +1772,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/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= @@ -1869,12 +1779,8 @@ golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/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-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1886,7 +1792,6 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w 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-20200124204421-9fbb57f87de9/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= @@ -1914,7 +1819,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1926,11 +1830,9 @@ golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/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-20210511113859-b0526f3d8744/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-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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= @@ -1941,19 +1843,33 @@ golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/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-20211205182925-97ca703d548d/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-20220114195835-da31bd327af9/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-20220315194320-039c03cc5b86/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-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1970,14 +1886,13 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= -golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190125232054-d66bd3c5d5a6/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= @@ -1993,14 +1908,11 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/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-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -2057,16 +1969,17 @@ 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/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-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= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -2102,9 +2015,16 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6 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.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +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/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2164,6 +2084,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D 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-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210331142528-b7513248f0ba/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= @@ -2184,14 +2105,28 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc 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-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/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 h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= 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/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 h1:4SPz2GL2CXJt28MTF8V6Ap/9ZiVbQlJeGSd9qtA7DLs= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2225,9 +2160,12 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD 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.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +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 v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -2243,8 +2181,9 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7 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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -2266,9 +2205,8 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= @@ -2290,8 +2228,10 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/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-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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= diff --git a/integrations/gitea-integration-sqlite/data/jwt/private.pem b/integrations/gitea-integration-sqlite/data/jwt/private.pem new file mode 100644 index 000000000..185407da8 --- /dev/null +++ b/integrations/gitea-integration-sqlite/data/jwt/private.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDOJcU+Npexwx5F +6G8ubpXx9TJh/liBs9gMFE5N0z+eep7ljQUg8sFVXaditw57RZDV9VGG9oK3zhxG +4b3ZwUOJoJi7CokG9b4COO+/rKw24IuykiRb4jgC+rWWS7VBHmCrjMqK+uS+WnD6 +ubE2oH2OjLybcGEzlIx2Q+I8Y+9vhHpLjxjBH+OoLQEuCPiSxgGfvE8iE7/w2Ok3 +m7L7ZmYGS1oLQxT1ayTeBvfOvC6JLVAlugxdYm32rfbiZOLvcbwj86zAcqfN2HVd +DpGgEsZVKkwKBb/QwlyidbzWho/xIM424tGrknujgmj3OO6PHuRBrvSkQUD3gnaL +LvztOulI9VXVEWUJv5xga5i9p4x1kBn0TUj9z+CEJbwlLBiHaM3wBcCGZu3o/O8j +pDuC7UOaikM60uAyFjV+IFiyRlqFC0drvQYOvoFKTrzFj5EUa4219ruEdNE29HYq ++0JSYK8+Jm0NO80WCbQsMsjrpMDePDNpRQS8XFcSnThymdhspViaPBvYv/S26jJ5 +Y5VXROc3ImmWULe07hNOLTfR1yw/pnhsuhHPoLfO6Z+G8xYqUVxRIc8Ls9LmXoZq +m+x+uC7evtQln9ukQY9oqDX/e00/1it+332E5KytrS70ZdfIG8x1mGqFmNsMhfFC +AzuZp4ydfpyQwM9dexhRHo8fzUDOTwIDAQABAoICACa2OxMSx2vPW1j/bBmJFMlq +JTr3u4En17N1ALtmpzTIjBxJXiQw0hOI0c0c2TBXAPrc5aF1m1iO8Qpyi+dffqJS +sTu2n8LZ1QOv033oHDL1+eXfwcorch9FG2KM9w2yea7dco+ky93fOAYtZtT+UHW7 +ghOih+5awAHZf5udnLIRa7HSvnBN37+OLAGMF7ngSx/HCgk5Mjs1UJ5rs7G4KgKW +leM1hrMLmtHC9zgwaIDELJ/ZD0deG45OXuVm0qLqdc0+jjtZjJ+APZHrEXfA7tPB +bKQZLksypJixiXOzs0YxxefSslMI4AT1kWaTn2DrCSw4gaJyypNwQXijq0WVYYdG +aXarn1SaEVqgYNSAEqAArcB20dp9xPavFQtWUfwtXjGnhDuSxNf9y0+UGGZjwkpY +CWoDpigHpCiPvYkqiN3JzgcFhPWFEOxPPn5C23b4jrQnTPlIRuhlClvFcN+F8Ljt +Tv9dlNvpV+5R9mJDHVwGNQm09XctNfdLg6dlMeBJmAvZSpn7oG3EisguoQMfBxLG +8AXEuIYrT1vQRUwQdwqO+uzI7wlyxhADvA27yB2OYVaM7DjT6taXRgFA8YDJDcup +5+tH2emKSRKAvZ1tModImnjxzC0+KZ1TXcQZ2OzZK7Z0vj9pLUMAGle7grp3vFco +FGfzH4yWOik0ihjSIbD5AoIBAQD1rqRQVbUioftZdotSnhQMMZFnm062V3RSbMid +w0k/kIRpk19optdl/7KP1pwGMWfCW8l2489/Xng+AoYYcJwXcGW4NGSTboL+8lPb +NzyuLUO2e43ltrcuXElJWgTYqd1UF5TrpT9vIFMEsXKKRPbgWriRbFCFlf5InGC7 +whVr/KiFyDJgDEaV6rcGlk9wBzI84pwijooE8MLX29WWpXoC+4gCqvqVfYrjqMp/ +S+PFen2xYH8YxXPg0VblwOSMj+wsJsJrsly0UIg8LUJgPnYStXYKCb5lkkQ+TUUs +l8WqSuRIma5TeXpgoI5PnI0JgtHGORUxzt2W+wpl3GYrNIm1AoIBAQDWzhZAbOkK +xIFdsdods5MOrW7N6rqcUt2G+bGQEtXLVfHInCqSL6F6k7i7Mv1n+4szKPHTdtko +/Cturhnfc3Ydt24eB8neZBpzUsO3Wh3hfo01ji8nXTcdzdDO/q+HjusWGwvYAN4R +NbrlUIany1HZVq9JgX7bnmSyPJ13ose6Uci0wd6dwxes3G5RZ+pQWMYjpMqdBmPu +HcHnEbfc3ah0QlfP7hLOdO3udQKjjYIhpxsNXE/SXqpMWsSlvhGkBtry9CuGF9G1 +gQIKZBgNZG/2TeB5UkOLy3tn3qNFYGc+bXXtjqX79baPn3VnuqHQgYI95kzz9eBP +JEGm+CGSWmpzAoIBAQDNNAB0RRIVCjyZXcVCzVwrTx+G7RaSgHtc+RWbh+hfWkLu +t7QiAfC5dhfbwkHxfkSO9wFP9zlxxiMikBMWyL/nZ+7eK4yyA8UQUrEt0XYyeQYs +nghIDRP1egmQZcrUeRSvTz8Ij65rEBGnQttLmAyoGb49YL3kxgJs/YhiatpfptnP +XAaPaNFwGGqk6tkQ1kHkztXgmzO2qq3jg+9jc3V0lkjlCZBhWkmum2X/axCk+gmQ +JOwjcZC2/8LYBgQfT3rQ6dLMB18dEIKp2JevMZyHRd+AxOCtj7zGWN3lQCNOeF0y +MoKDoFxR5ujWoAjBH+485aLJRmKY37ewmqUPg0NdAoIBAQCw6Zs6BHkK/TzuxgQ2 +YifD9uNDhQecqEL7X7r2Rgz/IxG3f6cwLzp3kiKbSyuZ8Hp88EP7Pe8s6kN7LLjy +aE3nu6Nd6FxCZX/Da272G6pwhaIXcbs0WHmEenZ3hRtcMkE8O5pNlKlQ00fShbfh +insm3VYQ3C53AsU8Zt/qII8OzTzYYrPOi1d8bzAMq+E3u2W1BYw6N4EmJCwG+3jK +12ReHCXmgtXKZFNyCbzapzl+LfsBzf2P7Zekuz0qpJgy19KMNr2B+ywkqNPdawLE +ROxRl2JBiZdIE5bXvW4LPZLKv6xYsxvRoFVzhIlVnUiYSZHTGVJXuzG6/Ml1kvdT +alQxAoIBACTwlLFIIQRfctKPvoXubcVgZtsMmABeQ1lp380zWxIlV9W8860AS0wn +doajsEL5sUzc8vTkKIxvLrMVJfF90kDYco3rHnKJ2CJPXBpdxkIBfOZk/szPdrwW +RUbFPzrp5zdCTjDEyTBsX8RN2/e/tjTPjtp4stvJ21zYHZKm2Y/69dsT+ua/bHKZ +Puxi8My1yPt70W9skBkNjPkRdP3rQHfGkwyU6fSC6LHGmkkTONHAJ/h3pxCZxYxj +fpNFBoN9X3Yg3QemDw/2nMystogGuxdeCA5RngmHrBejL4wuY1NAXGbRU5OOU7a5 +0+V5N7/gmEIIlkcBnnUMl6nalbU2dGU= +-----END PRIVATE KEY----- diff --git a/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa b/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa new file mode 100644 index 000000000..460aaa25e --- /dev/null +++ b/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAzO47zAU2RVAl0MKRW5GC8gAh9ZidC7zWsKXzC9onvfJy1Khe +2xIgomaht8SJOJ9mN6xBw6eIgRybfg5vvT6V1AJWc/BGaKo6xLDBwPNLxOUmmAHH +55I410R8mBOB8ZrJwxKT4TEXsMalK1cC5QhtKFkIDdEWtixBd7QzOyZf3Q8iAah9 +h5/Ae5KZ80pF/Axy4hKEdRFdYt4vTWJC2MMEzgqJRLPMHlXMrJyVqdXXTusKw2xi +V2gwoRk+IGpKHHghNUrXPMPiqe+/cd1VCB0pwwCWLvvaPNaJ4y9J6Uhlrj71pwpO +g0i0zqTpAJEaMZ6HbZA0IXBwZ+pXAxauoUNmP+MX2y3g7z4En5GdORTlF74h4H89 +y3uAxhOoARYjGlKKOnKCSbp/MNYKyQmhMKbV/338YD6z5zw47IdlJa2h+p+Ut6yc +1PBmMvLDb0jC1Q+syKykdO6e+r0yYFOIc+3b9RqSTOCiRrKsVmOLJMACrV3mV97M +WB50hCc6anHKbiIWcsO1zjUmLV2G6kmbwvLtfcpTC1yTlbdKNL81OYeBIc1xJHXx +3Rv6nVnYZ1PaSS5ZcKb3ARzj6W5O6VpvAefDVk404Z0XsG/5Oaa+KKx7Rg+ZSBeM +I9qdFchIU4jXG2CqOoIDP/mkWuDfyLuhJIMU845adocBuhfV3wkZvDhuX5ECAwEA +AQKCAgAXrV7TT7bZg00bNZ+9yK4sb798tMlQVd0oQ8Q1FluJIr4Ju/pZrVp/6QO+ +S8Le++u/evOOO4kWAcwlYF2gq957xFlgw94esaxglVuNg465jRBMd8g1BTv0A0Gy +AG7/DzdIhpj3Z8io8AqdW0xGUhbqln7LueC545sczYEt0F07GUiAkIsQZHDE1kdb +SLWVTYroe+M582uqxKkKc9PtX3rqo2UAvxVSW+9t8hmIqeBaieWQdrFWD/+uXVBE +RoORjn+nvKHpr2g84ipoaX4tldEBasvvWcH5TYBY81nCzk6RN00Co7o2iOv7BCq3 +mgxAt2RGUGb1hhw2pWiwPqqmjzb87a1jMpW1k8DFVxmJRzllmcWEjxRy7pE9s5Ou +YsbUjrdFjIVNPc1MvlXDunMtRxIB9GUI9Y5DtvzpJMVtTllVTbNHXr1257Uv64QE +W6dwgoUF/x8mX2dWyjRsJ1goGpwvoCw9PWzSYmfoIQ3wkjxfGWAsvjihWFrm8IRt +D71zNthgbAdYN+ImsXszcM+MBfcex7VK75CLHxM7RlfRUtQwWdNrSqI8v/mKu3iz +WpStYb/9dGFH45w0q+NheD69Erp9PIBTG83noCyT+c2K61jod77+XQCF00xYjq6D +FzlWN5YFqxoOmju+D9LmZYPEVq0cnNwQScQy1gnfNfJA9Oxn0QKCAQEA2c7exvaY +QX0ONUFws2Qo7F3DNI7qa4e91UZEKrjCdbd2Ad4WPG8wKf/xTXVtnZCiwUI634Ql +7eH4XV8WWQSI3zJnen/dVwhgbKoJXY+oG8VI2tAlwL+Z1OjpJ75A2CzM231qnlVO +MYKEfUz5n6sgAbZJuiqDaCrINJ8tzSjI2ZqVvnpxM5wE4Us4C9mKRhRsDxAKs5b4 +HsYeujWANRCuNHEi9m8mGF8pB7vmDYjzay191w/ArjzXulSandu2Gfsa8r+mcwDA +W5H9FSRddUNAEMp1dHirSFHaqtSyg0nKvbJsZp/pZuCD7vmw3czH9mz106psxFfo +/AL8IMHRedqYNwKCAQEA8N1PKrSCwM+/ExlemfEDzxdXJvJtvXk52Oii3xFhjBf/ +rhO146xiMFpKitjfOXBVFTR86qPhCz3uSsyDxodpq4nEBiIvi/mgMU8XORomzQo8 +vPbhAvH3gc4vxlpg+JlPC/egEqDSqjKGRT4/rRb/+vpuNterS/wiEd39WPM6TV27 +EA7/cw6Z9b7X1hFOQvzhoJ4yZcrkvgghmLTQoNMQztTT/VzesstfDfjXttUOJBa+ +VBIcszat5XjXeNDIk4K447jcoXfJD8xjKl10XVxobKMSD/pbXeJtudCcXXC7Tk2A +ca1jrmiuY5lXAd05cOJNLkpwEkzj1KqLSApUQXBSdwKCAQEAqBRaGlQFntPweOxt +GiJ66hxZHWAESsLPnZvB0u4NMmZHLJ3DrxNmqaKXBd1On78TuetwHziNRIuS7AsK +5dr3/LWa4Q93MUiHkJOO8qJ/ah7OX/0shRfWkFTESCUrSScZV2/rLRBLbS15LHCQ +WcTmyCtxrbZM/b+2C9WitKV6iWIfmIRIgzktEubG824GpJnx4ZXRjFE+XBEreSr8 +KvcaV+HOxzlyvnAA67T2jQ9YOSc76xB+8naFS4cqYhNA7b+3RgjbW/gCeSepk/0i +GfGxqMNz7FOKah6wjg/hSitRxx2/RVq19OvhJDOPZzo2PVZMRfFISiRE6OUsx+KJ +0mz79QKCAQALzRwS4JNDdSpMekK7Uia4n9EiVGByFx1xdjx8p3JbFdXuJoMT659H +9TSPxv5w5wMULeUs7eiZz2f8fDa8pGfWAsL69fPUbN+fatudbZ2XEDhXndT6evaA +gqSumEEGDSTlVjWelAieVCll/R3LkkPqfRinUTvQVkMpEvJVyF0D62K9764uafm7 +I6WZlHF8ML2xS+72M9GvSeCzhbBvIMhDCgR09nbm1bYLjjSrfZbax859egGz+ird +AmW0Qq6BI7eBWM5ejurn/kChk8CezmdDY14AMGkHmY98ui7fGSXkOUHgz/kBU5mv +wZSUv80PrdbQPM9u5huHkO+QEQl9x04TAoIBAFPSAJ672WC/rDgQoBo155bi1Qox +jXCkuu9KRTYZAcVB3fpwoSh2Caj4qRLQbqknk5ADbJfHCYeN52J0JFSaVAkwWB+F +SmXFGxvLhW15CX2Blxcj1FruC7Hi9G6WoBm71fADRok2HdOXve4oGO7j7k3LtTvZ +Mq5+L9XVHA6VmZvvpjdo54PRxri8HWoIcBLNWlqJe8N8dJe972l94jJjkkT5dWHl +0eE/9A3mHHS0HU9SZoGT+ZNtgny1ZkH0kgiTXhB8yvHYme0A5qZ1g7tRgC/Ra29d +bA/85c9Yf4ggvA2GfU40XFEtMePkEF26arVAAkvUSHLBCMCdx8rjUaY+vLs= +-----END RSA PRIVATE KEY----- diff --git a/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa.pub b/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa.pub new file mode 100644 index 000000000..09c9839f1 --- /dev/null +++ b/integrations/gitea-integration-sqlite/data/ssh/gitea.rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDM7jvMBTZFUCXQwpFbkYLyACH1mJ0LvNawpfML2ie98nLUqF7bEiCiZqG3xIk4n2Y3rEHDp4iBHJt+Dm+9PpXUAlZz8EZoqjrEsMHA80vE5SaYAcfnkjjXRHyYE4HxmsnDEpPhMRewxqUrVwLlCG0oWQgN0Ra2LEF3tDM7Jl/dDyIBqH2Hn8B7kpnzSkX8DHLiEoR1EV1i3i9NYkLYwwTOColEs8weVcysnJWp1ddO6wrDbGJXaDChGT4gakoceCE1Stc8w+Kp779x3VUIHSnDAJYu+9o81onjL0npSGWuPvWnCk6DSLTOpOkAkRoxnodtkDQhcHBn6lcDFq6hQ2Y/4xfbLeDvPgSfkZ05FOUXviHgfz3Le4DGE6gBFiMaUoo6coJJun8w1grJCaEwptX/ffxgPrPnPDjsh2UlraH6n5S3rJzU8GYy8sNvSMLVD6zIrKR07p76vTJgU4hz7dv1GpJM4KJGsqxWY4skwAKtXeZX3sxYHnSEJzpqccpuIhZyw7XONSYtXYbqSZvC8u19ylMLXJOVt0o0vzU5h4EhzXEkdfHdG/qdWdhnU9pJLllwpvcBHOPpbk7pWm8B58NWTjThnRewb/k5pr4orHtGD5lIF4wj2p0VyEhTiNcbYKo6ggM/+aRa4N/Iu6EkgxTzjlp2hwG6F9XfCRm8OG5fkQ== diff --git a/integrations/gitea-integration-sqlite/gitea-repositories/.gitconfig b/integrations/gitea-integration-sqlite/gitea-repositories/.gitconfig new file mode 100644 index 000000000..66d40567c --- /dev/null +++ b/integrations/gitea-integration-sqlite/gitea-repositories/.gitconfig @@ -0,0 +1,11 @@ +[user] + name = Gitea + email = gitea@fake.local +[core] + quotePath = false + commitGraph = true +[receive] + advertisePushOptions = true + procReceiveRefs = refs/for +[gc] + writeCommitGraph = true diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/HEAD diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/config similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/config diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/description similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/description diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/info/exclude diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/74/8bf557dfc9c6457998b5118a6c8b2129f56c30 b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/74/8bf557dfc9c6457998b5118a6c8b2129f56c30 similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/74/8bf557dfc9c6457998b5118a6c8b2129f56c30 rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/74/8bf557dfc9c6457998b5118a6c8b2129f56c30 diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/a5/46f86c7dd182592b96639045e176dde8df76ef b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/a5/46f86c7dd182592b96639045e176dde8df76ef similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/a5/46f86c7dd182592b96639045e176dde8df76ef rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/a5/46f86c7dd182592b96639045e176dde8df76ef diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/b8/95782bd271fdd266dd06e5880ea4abdc3a0dc7 b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/b8/95782bd271fdd266dd06e5880ea4abdc3a0dc7 similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/objects/b8/95782bd271fdd266dd06e5880ea4abdc3a0dc7 rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/objects/b8/95782bd271fdd266dd06e5880ea4abdc3a0dc7 diff --git a/integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/private_repo_on_limited_org.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/private_repo_on_limited_org.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/HEAD diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/config similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/config diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/description similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/description diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/info/exclude diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/21/2f14c8b713de38bd0b3fb23bd288369b01668a b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/21/2f14c8b713de38bd0b3fb23bd288369b01668a similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/21/2f14c8b713de38bd0b3fb23bd288369b01668a rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/21/2f14c8b713de38bd0b3fb23bd288369b01668a diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/90/e402c3937a4639725fcc59ca1f529e7dc8506f b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/90/e402c3937a4639725fcc59ca1f529e7dc8506f similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/90/e402c3937a4639725fcc59ca1f529e7dc8506f rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/90/e402c3937a4639725fcc59ca1f529e7dc8506f diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/ed/d9c1000cd1444efd63e153e3554c8d5656bf65 b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/ed/d9c1000cd1444efd63e153e3554c8d5656bf65 similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/objects/ed/d9c1000cd1444efd63e153e3554c8d5656bf65 rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/objects/ed/d9c1000cd1444efd63e153e3554c8d5656bf65 diff --git a/integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/limited_org/public_repo_on_limited_org.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/limited_org/public_repo_on_limited_org.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/HEAD diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/config similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/config diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/description similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/description diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-checkout b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-checkout similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-checkout rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-checkout diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-commit b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-commit similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-commit rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-commit diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-merge b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-merge similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/post-merge rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/post-merge diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/pre-push b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/pre-push similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/hooks/pre-push rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/hooks/pre-push diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/index b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/index similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/index rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/index diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/lfs/objects/d6/f1/d6f175817f886ec6fbbc1515326465fa96c3bfd54a4ea06cfd6dbbd8340e0152 b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/lfs/objects/d6/f1/d6f175817f886ec6fbbc1515326465fa96c3bfd54a4ea06cfd6dbbd8340e0152 similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/lfs/objects/d6/f1/d6f175817f886ec6fbbc1515326465fa96c3bfd54a4ea06cfd6dbbd8340e0152 rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/lfs/objects/d6/f1/d6f175817f886ec6fbbc1515326465fa96c3bfd54a4ea06cfd6dbbd8340e0152 diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/lfs/objects/fb/8f/fb8f7d8435968c4f82a726a92395be4d16f2f63116caf36c8ad35c60831ab041 b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/lfs/objects/fb/8f/fb8f7d8435968c4f82a726a92395be4d16f2f63116caf36c8ad35c60831ab041 similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/lfs/objects/fb/8f/fb8f7d8435968c4f82a726a92395be4d16f2f63116caf36c8ad35c60831ab041 rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/lfs/objects/fb/8f/fb8f7d8435968c4f82a726a92395be4d16f2f63116caf36c8ad35c60831ab041 diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/objects/54/6244003622c64b2fc3c2cd544d7a29882c8383 b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/54/6244003622c64b2fc3c2cd544d7a29882c8383 similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/objects/54/6244003622c64b2fc3c2cd544d7a29882c8383 rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/54/6244003622c64b2fc3c2cd544d7a29882c8383 diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/objects/6a/6ccf5d874fec134ee712572cc03a0f2dd7afec b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/6a/6ccf5d874fec134ee712572cc03a0f2dd7afec similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/objects/6a/6ccf5d874fec134ee712572cc03a0f2dd7afec rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/6a/6ccf5d874fec134ee712572cc03a0f2dd7afec diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/objects/a6/7134b8484c2abe9fa954e1fd83b39b271383ed b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/a6/7134b8484c2abe9fa954e1fd83b39b271383ed similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/objects/a6/7134b8484c2abe9fa954e1fd83b39b271383ed rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/a6/7134b8484c2abe9fa954e1fd83b39b271383ed diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/objects/b7/01ed6ffe410f0c3ac204b929ea47cfec6cef54 b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/b7/01ed6ffe410f0c3ac204b929ea47cfec6cef54 similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/objects/b7/01ed6ffe410f0c3ac204b929ea47cfec6cef54 rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/b7/01ed6ffe410f0c3ac204b929ea47cfec6cef54 diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/objects/f2/07b74f55cd7f9e800b7550d587cbc488f6eaf1 b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/f2/07b74f55cd7f9e800b7550d587cbc488f6eaf1 similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/objects/f2/07b74f55cd7f9e800b7550d587cbc488f6eaf1 rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/objects/f2/07b74f55cd7f9e800b7550d587cbc488f6eaf1 diff --git a/integrations/gitea-repositories-meta/migration/lfs-test.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/migration/lfs-test.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/migration/lfs-test.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/COMMITMESSAGE b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/COMMITMESSAGE similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/COMMITMESSAGE rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/COMMITMESSAGE diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/COMMIT_EDITMSG b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/COMMIT_EDITMSG similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/COMMIT_EDITMSG rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/COMMIT_EDITMSG diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/HEAD diff --git a/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/config new file mode 100644 index 000000000..2768a2037 --- /dev/null +++ b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = false + logallrefupdates = true + symlinks = false + ignorecase = true +[user] + name = user2 + email = user2@example.com diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/config.backup b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/config.backup similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/config.backup rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/config.backup diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/description similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/description diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/index b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/index similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/index rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/index diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/info/exclude diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/HEAD diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/logs/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/logs/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/COMMITMESSAGE b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/COMMITMESSAGE similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/COMMITMESSAGE rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/COMMITMESSAGE diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/COMMIT_EDITMSG b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/COMMIT_EDITMSG similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/COMMIT_EDITMSG rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/COMMIT_EDITMSG diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/HEAD diff --git a/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/config new file mode 100644 index 000000000..2768a2037 --- /dev/null +++ b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = false + logallrefupdates = true + symlinks = false + ignorecase = true +[user] + name = user2 + email = user2@example.com diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/config.backup b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/config.backup similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/config.backup rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/config.backup diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/description similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/description diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/index b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/index similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/index rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/index diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/info/exclude diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/HEAD diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/logs/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/logs/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_alpha.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_alpha.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/COMMITMESSAGE b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/COMMITMESSAGE similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/COMMITMESSAGE rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/COMMITMESSAGE diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/COMMIT_EDITMSG b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/COMMIT_EDITMSG similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/COMMIT_EDITMSG rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/COMMIT_EDITMSG diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/HEAD diff --git a/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/config new file mode 100644 index 000000000..2768a2037 --- /dev/null +++ b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = false + logallrefupdates = true + symlinks = false + ignorecase = true +[user] + name = user2 + email = user2@example.com diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/config.backup b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/config.backup similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/config.backup rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/config.backup diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/description similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/description diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/index b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/index similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/index rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/index diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/info/exclude diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/HEAD diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/logs/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/logs/refs/heads/master diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/ba/ea7d6e6b7773a80bcede323cfb21dfe9d4b855 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/c2/a1ad4c931cebe27c7e39176fe7119b5557c9eb diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/objects/cd/aca8cf1d36e1e4e508a940f6e157e239beccfa diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/refs/heads/branch1 b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/refs/heads/branch1 similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/refs/heads/branch1 rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/refs/heads/branch1 diff --git a/integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/org26/repo_external_tracker_numeric.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/org26/repo_external_tracker_numeric.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/HEAD diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/config similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/config diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/description similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/description diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/info/exclude diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/6e/75c9f89da9a9b93f4f36e61ed092f7a1625ba0 b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/6e/75c9f89da9a9b93f4f36e61ed092f7a1625ba0 similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/6e/75c9f89da9a9b93f4f36e61ed092f7a1625ba0 rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/6e/75c9f89da9a9b93f4f36e61ed092f7a1625ba0 diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/7f/eb6f9dd600e17a04f48a76cfa0a56a3f30e2c1 b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/7f/eb6f9dd600e17a04f48a76cfa0a56a3f30e2c1 similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/7f/eb6f9dd600e17a04f48a76cfa0a56a3f30e2c1 rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/7f/eb6f9dd600e17a04f48a76cfa0a56a3f30e2c1 diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/b7/91b41c0ae8cb3c4b12f3fd8c3709c2481d9e37 b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/b7/91b41c0ae8cb3c4b12f3fd8c3709c2481d9e37 similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/objects/b7/91b41c0ae8cb3c4b12f3fd8c3709c2481d9e37 rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/objects/b7/91b41c0ae8cb3c4b12f3fd8c3709c2481d9e37 diff --git a/integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/private_repo_on_private_org.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/private_repo_on_private_org.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/HEAD diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/config similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/config diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/description similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/description diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/info/exclude diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/04/f99c528b643b9175a4b156cdfc13aba6b43853 b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/04/f99c528b643b9175a4b156cdfc13aba6b43853 similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/04/f99c528b643b9175a4b156cdfc13aba6b43853 rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/04/f99c528b643b9175a4b156cdfc13aba6b43853 diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/86/de16d8658f5c0a17ec6aa313871295d7072f78 b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/86/de16d8658f5c0a17ec6aa313871295d7072f78 similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/86/de16d8658f5c0a17ec6aa313871295d7072f78 rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/86/de16d8658f5c0a17ec6aa313871295d7072f78 diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/bf/19fd4707acb403c4aca44f126ab69142ac59ce b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/bf/19fd4707acb403c4aca44f126ab69142ac59ce similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/objects/bf/19fd4707acb403c4aca44f126ab69142ac59ce rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/objects/bf/19fd4707acb403c4aca44f126ab69142ac59ce diff --git a/integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/privated_org/public_repo_on_private_org.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/privated_org/public_repo_on_private_org.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/HEAD diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/config diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/description diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/info/refs diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/DefaultBranch b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/DefaultBranch similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/DefaultBranch rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/DefaultBranch diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/develop b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/develop similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/develop rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/develop diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/feature/1 b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/feature/1 similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/feature/1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/feature/1 diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user12/repo10.git/refs/tags/v1.1 b/integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/tags/v1.1 similarity index 100% rename from integrations/gitea-repositories-meta/user12/repo10.git/refs/tags/v1.1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user12/repo10.git/refs/tags/v1.1 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/HEAD diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/config diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/description diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/info/refs diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/0a/bcb056019adb8336cf9db3ad9d9cf80cd4b141 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/0a/bcb056019adb8336cf9db3ad9d9cf80cd4b141 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/0a/bcb056019adb8336cf9db3ad9d9cf80cd4b141 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/0a/bcb056019adb8336cf9db3ad9d9cf80cd4b141 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/75/d1afd00e111c8dbd9e3d96a27b431ac5ae6d74 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/75/d1afd00e111c8dbd9e3d96a27b431ac5ae6d74 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/75/d1afd00e111c8dbd9e3d96a27b431ac5ae6d74 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/75/d1afd00e111c8dbd9e3d96a27b431ac5ae6d74 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/ed/447543e0c85d628b91f7f466f4921908f4c5ea b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/ed/447543e0c85d628b91f7f466f4921908f4c5ea similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/ed/447543e0c85d628b91f7f466f4921908f4c5ea rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/ed/447543e0c85d628b91f7f466f4921908f4c5ea diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/DefaultBranch b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/DefaultBranch similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/DefaultBranch rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/DefaultBranch diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/branch2 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/branch2 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/branch2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/branch2 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/develop b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/develop similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/develop rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/develop diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/feature/1 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/feature/1 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/feature/1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/feature/1 diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user13/repo11.git/refs/tags/v1.1 b/integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/tags/v1.1 similarity index 100% rename from integrations/gitea-repositories-meta/user13/repo11.git/refs/tags/v1.1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user13/repo11.git/refs/tags/v1.1 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/config diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/description diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/0a/8499a22ad32a80beda9d75efe15f9f94582468 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/0a/8499a22ad32a80beda9d75efe15f9f94582468 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/0a/8499a22ad32a80beda9d75efe15f9f94582468 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/0a/8499a22ad32a80beda9d75efe15f9f94582468 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/0c/cf1fcd4d1717c22de0707619a5577ea0acebf0 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/0c/cf1fcd4d1717c22de0707619a5577ea0acebf0 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/0c/cf1fcd4d1717c22de0707619a5577ea0acebf0 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/0c/cf1fcd4d1717c22de0707619a5577ea0acebf0 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/3e/a192a6466793d4b7cd8641801ca0c6bec3979c b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/3e/a192a6466793d4b7cd8641801ca0c6bec3979c similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/3e/a192a6466793d4b7cd8641801ca0c6bec3979c rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/3e/a192a6466793d4b7cd8641801ca0c6bec3979c diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/3f/6594f108842b7c50772510e53ce113d3583c4a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/3f/6594f108842b7c50772510e53ce113d3583c4a similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/3f/6594f108842b7c50772510e53ce113d3583c4a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/3f/6594f108842b7c50772510e53ce113d3583c4a diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/58/e97d1a24fb9e1599d8a467ec409430f3d3569e b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/58/e97d1a24fb9e1599d8a467ec409430f3d3569e similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/58/e97d1a24fb9e1599d8a467ec409430f3d3569e rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/58/e97d1a24fb9e1599d8a467ec409430f3d3569e diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/67/68c1fc1d9448422f05cc84267d94ee62085fe8 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/67/68c1fc1d9448422f05cc84267d94ee62085fe8 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/67/68c1fc1d9448422f05cc84267d94ee62085fe8 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/67/68c1fc1d9448422f05cc84267d94ee62085fe8 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/6e/8eabd9a7f8d6acd2a1219facfd37415564b144 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/6e/8eabd9a7f8d6acd2a1219facfd37415564b144 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/6e/8eabd9a7f8d6acd2a1219facfd37415564b144 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/6e/8eabd9a7f8d6acd2a1219facfd37415564b144 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/85/f46d747a68adf79cc01e2c25ba6a56932d298d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/85/f46d747a68adf79cc01e2c25ba6a56932d298d similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/85/f46d747a68adf79cc01e2c25ba6a56932d298d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/85/f46d747a68adf79cc01e2c25ba6a56932d298d diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/8d/dd8d1ad1fdc21ab629e906711fa9bc27aa1c52 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/8d/dd8d1ad1fdc21ab629e906711fa9bc27aa1c52 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/8d/dd8d1ad1fdc21ab629e906711fa9bc27aa1c52 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/8d/dd8d1ad1fdc21ab629e906711fa9bc27aa1c52 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/95/fd0c4138480e4b3913e7cf71a90623fb926fe8 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/95/fd0c4138480e4b3913e7cf71a90623fb926fe8 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/95/fd0c4138480e4b3913e7cf71a90623fb926fe8 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/95/fd0c4138480e4b3913e7cf71a90623fb926fe8 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/98/00fe78cabf4fe774fcf376f97fa2a0ed06987b b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/98/00fe78cabf4fe774fcf376f97fa2a0ed06987b similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/98/00fe78cabf4fe774fcf376f97fa2a0ed06987b rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/98/00fe78cabf4fe774fcf376f97fa2a0ed06987b diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/9f/cdb7d53bdef786d2e5577948a0c0d4b321fe5a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/9f/cdb7d53bdef786d2e5577948a0c0d4b321fe5a similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/9f/cdb7d53bdef786d2e5577948a0c0d4b321fe5a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/9f/cdb7d53bdef786d2e5577948a0c0d4b321fe5a diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/c2/0caf78b5f9dd2d0d183876c5cd0e761c13f7f8 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/c2/0caf78b5f9dd2d0d183876c5cd0e761c13f7f8 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/c2/0caf78b5f9dd2d0d183876c5cd0e761c13f7f8 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/c2/0caf78b5f9dd2d0d183876c5cd0e761c13f7f8 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/c5/2ba74685f5c8c593efbbb38f62fe024110adef b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/c5/2ba74685f5c8c593efbbb38f62fe024110adef similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/c5/2ba74685f5c8c593efbbb38f62fe024110adef rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/c5/2ba74685f5c8c593efbbb38f62fe024110adef diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/d6/ae8023a10ff446b6a4e7f441554834008e99c3 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/d6/ae8023a10ff446b6a4e7f441554834008e99c3 similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/objects/d6/ae8023a10ff446b6a4e7f441554834008e99c3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/objects/d6/ae8023a10ff446b6a4e7f441554834008e99c3 diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/packed-refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/packed-refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/packed-refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/packed-refs diff --git a/integrations/gitea-repositories-meta/user2/commits_search_test.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/commits_search_test.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/commits_search_test.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/config diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/description diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive.d/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive.d/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/pre-receive.d/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/pre-receive.d/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/info/refs diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/DefaultBranch b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/DefaultBranch similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/DefaultBranch rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/DefaultBranch diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/develop b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/develop similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/develop rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/develop diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/feature/1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/feature/1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/feature/1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/feature/1 diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/tags/v1.1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/tags/v1.1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/git_hooks_test.git/refs/tags/v1.1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/git_hooks_test.git/refs/tags/v1.1 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/glob.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/config diff --git a/integrations/gitea-repositories-meta/user2/glob.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/description diff --git a/integrations/gitea-repositories-meta/user2/glob.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/48/06cb9df135782b818c968c2fadbd2c150d23d6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/48/06cb9df135782b818c968c2fadbd2c150d23d6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/48/06cb9df135782b818c968c2fadbd2c150d23d6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/48/06cb9df135782b818c968c2fadbd2c150d23d6 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/59/fee614e09d1f1cd1e15e4b2a7e9c8873a81498 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/59/fee614e09d1f1cd1e15e4b2a7e9c8873a81498 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/59/fee614e09d1f1cd1e15e4b2a7e9c8873a81498 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/59/fee614e09d1f1cd1e15e4b2a7e9c8873a81498 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/7c/8ac2f8d82a1eb5f6aaece6629ff11015f91eb4 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/7c/8ac2f8d82a1eb5f6aaece6629ff11015f91eb4 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/7c/8ac2f8d82a1eb5f6aaece6629ff11015f91eb4 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/7c/8ac2f8d82a1eb5f6aaece6629ff11015f91eb4 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/8e/592e636d27ac144f92f7fe8c33631cbdea594d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/8e/592e636d27ac144f92f7fe8c33631cbdea594d similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/8e/592e636d27ac144f92f7fe8c33631cbdea594d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/8e/592e636d27ac144f92f7fe8c33631cbdea594d diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/95/aff026f99a9ab76fbd01decb63dd3dbc03e498 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/95/aff026f99a9ab76fbd01decb63dd3dbc03e498 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/95/aff026f99a9ab76fbd01decb63dd3dbc03e498 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/95/aff026f99a9ab76fbd01decb63dd3dbc03e498 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/ae/d1ffed24cc3cf9b80490795e893cae4bddd684 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/ae/d1ffed24cc3cf9b80490795e893cae4bddd684 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/ae/d1ffed24cc3cf9b80490795e893cae4bddd684 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/ae/d1ffed24cc3cf9b80490795e893cae4bddd684 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/bf/d6a6583f9a9ac59bd726c1df26c64a89427ede b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/bf/d6a6583f9a9ac59bd726c1df26c64a89427ede similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/bf/d6a6583f9a9ac59bd726c1df26c64a89427ede rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/bf/d6a6583f9a9ac59bd726c1df26c64a89427ede diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/c8/eb3b6c767ccb68411d0a1f6c769be69fb4d95a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/c8/eb3b6c767ccb68411d0a1f6c769be69fb4d95a similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/c8/eb3b6c767ccb68411d0a1f6c769be69fb4d95a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/c8/eb3b6c767ccb68411d0a1f6c769be69fb4d95a diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/de/6be43fe8eb19ca3f4e934cb8b9a9a0b20fe865 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/de/6be43fe8eb19ca3f4e934cb8b9a9a0b20fe865 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/de/6be43fe8eb19ca3f4e934cb8b9a9a0b20fe865 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/de/6be43fe8eb19ca3f4e934cb8b9a9a0b20fe865 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/objects/ef/6b814b610d8e7717aa0f71fbe5842bcf814697 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/ef/6b814b610d8e7717aa0f71fbe5842bcf814697 similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/objects/ef/6b814b610d8e7717aa0f71fbe5842bcf814697 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/objects/ef/6b814b610d8e7717aa0f71fbe5842bcf814697 diff --git a/integrations/gitea-repositories-meta/user2/glob.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/glob.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/glob.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/info/refs diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/00/750edc07d6415dcc07ae0351e9397b0222b7ba b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/00/750edc07d6415dcc07ae0351e9397b0222b7ba similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/00/750edc07d6415dcc07ae0351e9397b0222b7ba rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/00/750edc07d6415dcc07ae0351e9397b0222b7ba diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/2a/2f1d4670728a2e10049e345bd7a276468beab6 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/3f/a2f829675543ecfc16b2891aebe8bf0608a8f4 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/3f/a2f829675543ecfc16b2891aebe8bf0608a8f4 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/3f/a2f829675543ecfc16b2891aebe8bf0608a8f4 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/3f/a2f829675543ecfc16b2891aebe8bf0608a8f4 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/4a/357436d925b5c974181ff12a994538ddc5a269 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/4a/357436d925b5c974181ff12a994538ddc5a269 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/4a/357436d925b5c974181ff12a994538ddc5a269 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/4a/357436d925b5c974181ff12a994538ddc5a269 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/4b/4851ad51df6a7d9f25c979345979eaeb5b349f diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/5c/050d3b6d2db231ab1f64e324f1b6b9a0b181c2 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/5c/050d3b6d2db231ab1f64e324f1b6b9a0b181c2 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/5c/050d3b6d2db231ab1f64e324f1b6b9a0b181c2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/5c/050d3b6d2db231ab1f64e324f1b6b9a0b181c2 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/5f/22f7d0d95d614d25a5b68592adb345a4b5c7fd b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/5f/22f7d0d95d614d25a5b68592adb345a4b5c7fd similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/5f/22f7d0d95d614d25a5b68592adb345a4b5c7fd rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/5f/22f7d0d95d614d25a5b68592adb345a4b5c7fd diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/62/fb502a7172d4453f0322a2cc85bddffa57f07a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/62/fb502a7172d4453f0322a2cc85bddffa57f07a similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/62/fb502a7172d4453f0322a2cc85bddffa57f07a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/62/fb502a7172d4453f0322a2cc85bddffa57f07a diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/65/f1bf27bc3bf70f64657658635e66094edbcb4d diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/6a/a3a5385611c5eb8986c9961a9c34a93cbaadfb b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/6a/a3a5385611c5eb8986c9961a9c34a93cbaadfb similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/6a/a3a5385611c5eb8986c9961a9c34a93cbaadfb rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/6a/a3a5385611c5eb8986c9961a9c34a93cbaadfb diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/7c/4df115542e05c700f297519e906fd63c9c9804 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/7c/4df115542e05c700f297519e906fd63c9c9804 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/7c/4df115542e05c700f297519e906fd63c9c9804 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/7c/4df115542e05c700f297519e906fd63c9c9804 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/90/dcd07da077d1e7cd6032b52d1f79ae2b5f19b2 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/90/dcd07da077d1e7cd6032b52d1f79ae2b5f19b2 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/90/dcd07da077d1e7cd6032b52d1f79ae2b5f19b2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/90/dcd07da077d1e7cd6032b52d1f79ae2b5f19b2 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/94/922e1295c678267de1193b7b84ad8a086c27f9 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/94/922e1295c678267de1193b7b84ad8a086c27f9 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/94/922e1295c678267de1193b7b84ad8a086c27f9 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/94/922e1295c678267de1193b7b84ad8a086c27f9 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/98/5f0301dba5e7b34be866819cd15ad3d8f508ee b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/98/5f0301dba5e7b34be866819cd15ad3d8f508ee similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/98/5f0301dba5e7b34be866819cd15ad3d8f508ee rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/98/5f0301dba5e7b34be866819cd15ad3d8f508ee diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/a6/9277c81e90b98a7c0ab25b042a6e296da8eb9a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/a6/9277c81e90b98a7c0ab25b042a6e296da8eb9a similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/a6/9277c81e90b98a7c0ab25b042a6e296da8eb9a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/a6/9277c81e90b98a7c0ab25b042a6e296da8eb9a diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/a7/57c0ea621e63d0fd6fc353a175fdc7199e5d1d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/a7/57c0ea621e63d0fd6fc353a175fdc7199e5d1d similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/a7/57c0ea621e63d0fd6fc353a175fdc7199e5d1d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/a7/57c0ea621e63d0fd6fc353a175fdc7199e5d1d diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/b2/60587271671842af0b036e4fe643c9d45b7ddd b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/b2/60587271671842af0b036e4fe643c9d45b7ddd similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/b2/60587271671842af0b036e4fe643c9d45b7ddd rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/b2/60587271671842af0b036e4fe643c9d45b7ddd diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/d4/a1a6dcf7bd42891f264d484e80dac7e66b5410 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/d4/a1a6dcf7bd42891f264d484e80dac7e66b5410 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/d4/a1a6dcf7bd42891f264d484e80dac7e66b5410 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/d4/a1a6dcf7bd42891f264d484e80dac7e66b5410 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/d7/bd5b8cfb680f460e37b6fd7cf74c284e059118 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/d7/bd5b8cfb680f460e37b6fd7cf74c284e059118 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/d7/bd5b8cfb680f460e37b6fd7cf74c284e059118 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/d7/bd5b8cfb680f460e37b6fd7cf74c284e059118 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/dc/7a8ba127fee870dd683310ce660dfe59333a1b b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/dc/7a8ba127fee870dd683310ce660dfe59333a1b similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/dc/7a8ba127fee870dd683310ce660dfe59333a1b rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/dc/7a8ba127fee870dd683310ce660dfe59333a1b diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/dd/59742c0f6672911f2b64cba5711ac00593ed32 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/dd/59742c0f6672911f2b64cba5711ac00593ed32 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/dd/59742c0f6672911f2b64cba5711ac00593ed32 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/dd/59742c0f6672911f2b64cba5711ac00593ed32 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/DefaultBranch b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/DefaultBranch similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/DefaultBranch rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/DefaultBranch diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/branch2 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/branch2 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/branch2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/branch2 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/develop b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/develop similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/develop rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/develop diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/feature/1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/feature/1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/feature/1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/feature/1 diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/pr-to-update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/pr-to-update similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/heads/pr-to-update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/heads/pr-to-update diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/notes/commits b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/notes/commits similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/notes/commits rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/notes/commits diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/2/head b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/2/head similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/2/head rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/2/head diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/3/head b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/3/head similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/3/head rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/3/head diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/5/head b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/5/head similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/pull/5/head rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/pull/5/head diff --git a/integrations/gitea-repositories-meta/user2/repo1.git/refs/tags/v1.1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/tags/v1.1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.git/refs/tags/v1.1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.git/refs/tags/v1.1 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/0d/ca5bd9b5d7ef937710e056f575e86c0184ba85 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/0d/ca5bd9b5d7ef937710e056f575e86c0184ba85 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/0d/ca5bd9b5d7ef937710e056f575e86c0184ba85 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/0d/ca5bd9b5d7ef937710e056f575e86c0184ba85 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/2c/54faec6c45d31c1abfaecdab471eac6633738a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/2c/54faec6c45d31c1abfaecdab471eac6633738a similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/2c/54faec6c45d31c1abfaecdab471eac6633738a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/2c/54faec6c45d31c1abfaecdab471eac6633738a diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/89/43a1d5f93c00439d5ffc0f8e36f5d60abae46c b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/89/43a1d5f93c00439d5ffc0f8e36f5d60abae46c similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/89/43a1d5f93c00439d5ffc0f8e36f5d60abae46c rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/89/43a1d5f93c00439d5ffc0f8e36f5d60abae46c diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/e5/3d079e581fbfdea1075a54d5b621eab0090e52 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/e5/3d079e581fbfdea1075a54d5b621eab0090e52 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/e5/3d079e581fbfdea1075a54d5b621eab0090e52 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/e5/3d079e581fbfdea1075a54d5b621eab0090e52 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/ea/82fc8777a24b07c26b3a4bf4e2742c03733eab b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/ea/82fc8777a24b07c26b3a4bf4e2742c03733eab similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/ea/82fc8777a24b07c26b3a4bf4e2742c03733eab rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/ea/82fc8777a24b07c26b3a4bf4e2742c03733eab diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 diff --git a/integrations/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo1.wiki.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo1.wiki.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo15.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo15.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo15.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/0c/3d59dea27b97aa3cb66072745d7a2c51a7a8b1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/0c/3d59dea27b97aa3cb66072745d7a2c51a7a8b1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/0c/3d59dea27b97aa3cb66072745d7a2c51a7a8b1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/0c/3d59dea27b97aa3cb66072745d7a2c51a7a8b1 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/24/f83a471f77579fea57bac7255d6e64e70fce1c b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/24/f83a471f77579fea57bac7255d6e64e70fce1c similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/24/f83a471f77579fea57bac7255d6e64e70fce1c rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/24/f83a471f77579fea57bac7255d6e64e70fce1c diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/27/566bd5738fc8b4e3fef3c5e72cce608537bd95 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/27/566bd5738fc8b4e3fef3c5e72cce608537bd95 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/27/566bd5738fc8b4e3fef3c5e72cce608537bd95 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/27/566bd5738fc8b4e3fef3c5e72cce608537bd95 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/3b/2b54fe3d9a8279d5b926124dccdf279b8eff2f b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/3b/2b54fe3d9a8279d5b926124dccdf279b8eff2f similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/3b/2b54fe3d9a8279d5b926124dccdf279b8eff2f rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/3b/2b54fe3d9a8279d5b926124dccdf279b8eff2f diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/45/8121ce9a6b855c9733bae62093caf3f39685de b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/45/8121ce9a6b855c9733bae62093caf3f39685de similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/45/8121ce9a6b855c9733bae62093caf3f39685de rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/45/8121ce9a6b855c9733bae62093caf3f39685de diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/50/99b81332712fe655e34e8dd63574f503f61811 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/50/99b81332712fe655e34e8dd63574f503f61811 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/50/99b81332712fe655e34e8dd63574f503f61811 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/50/99b81332712fe655e34e8dd63574f503f61811 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/69/554a64c1e6030f051e5c3f94bfbd773cd6a324 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/69/554a64c1e6030f051e5c3f94bfbd773cd6a324 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/69/554a64c1e6030f051e5c3f94bfbd773cd6a324 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/69/554a64c1e6030f051e5c3f94bfbd773cd6a324 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/a4/3476a501516e065c5a82f05fd58fd319598bc1 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/a4/3476a501516e065c5a82f05fd58fd319598bc1 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/a4/3476a501516e065c5a82f05fd58fd319598bc1 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/a4/3476a501516e065c5a82f05fd58fd319598bc1 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/e9/4083fcdf1f10c545e9253a23c5e44a2ff68aac b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/e9/4083fcdf1f10c545e9253a23c5e44a2ff68aac similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/e9/4083fcdf1f10c545e9253a23c5e44a2ff68aac rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/e9/4083fcdf1f10c545e9253a23c5e44a2ff68aac diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/f2/7c2b2b03dcab38beaf89b0ab4ff61f6de63441 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/f2/7c2b2b03dcab38beaf89b0ab4ff61f6de63441 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/f2/7c2b2b03dcab38beaf89b0ab4ff61f6de63441 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/f2/7c2b2b03dcab38beaf89b0ab4ff61f6de63441 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/objects/f9/0451c72ef61a7645293d17b47be7a8e983da57 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/f9/0451c72ef61a7645293d17b47be7a8e983da57 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/objects/f9/0451c72ef61a7645293d17b47be7a8e983da57 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/objects/f9/0451c72ef61a7645293d17b47be7a8e983da57 diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/good-sign b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/good-sign similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/good-sign rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/good-sign diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/good-sign-not-yet-validated b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/good-sign-not-yet-validated similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/good-sign-not-yet-validated rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/good-sign-not-yet-validated diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/not-signed b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/not-signed similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo16.git/refs/heads/not-signed rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo16.git/refs/heads/not-signed diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/info/refs diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/0a/7d8b41ae9763e9a1743917396839d1791d49d0 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/0a/7d8b41ae9763e9a1743917396839d1791d49d0 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/0a/7d8b41ae9763e9a1743917396839d1791d49d0 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/0a/7d8b41ae9763e9a1743917396839d1791d49d0 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/0c/f15c3f66ec8384480ed9c3cf87c9e97fbb0ec3 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/10/32bbf17fbc0d9c95bb5418dabe8f8c99278700 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/10/32bbf17fbc0d9c95bb5418dabe8f8c99278700 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/10/32bbf17fbc0d9c95bb5418dabe8f8c99278700 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/10/32bbf17fbc0d9c95bb5418dabe8f8c99278700 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/1c/887eaa8d81fa86da7695d8f635cf17813eb422 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/1c/887eaa8d81fa86da7695d8f635cf17813eb422 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/1c/887eaa8d81fa86da7695d8f635cf17813eb422 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/1c/887eaa8d81fa86da7695d8f635cf17813eb422 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/26/f842bcad37fa40a1bb34cbb5ee219ee35d863d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/26/f842bcad37fa40a1bb34cbb5ee219ee35d863d similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/26/f842bcad37fa40a1bb34cbb5ee219ee35d863d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/26/f842bcad37fa40a1bb34cbb5ee219ee35d863d diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/32/5dc4f8e9344e6668f21536a69d5f1d4ed53ca3 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/36/fff01c8c9f722d49d53186abd27b5be8d85338 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/36/fff01c8c9f722d49d53186abd27b5be8d85338 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/36/fff01c8c9f722d49d53186abd27b5be8d85338 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/36/fff01c8c9f722d49d53186abd27b5be8d85338 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/42/3313fbd38093bb10d0c8387db9105409c6f196 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/71/911bf48766c7181518c1070911019fbb00b1fc diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/72/fc6251cc648e914c10009d31431fa2e38b9a20 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/74/d5a0d73db9b9ef7aa9978eb7a099b08f54d45e diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/7c/d7c8fa852973c72c66eb120a6677c54a8697f7 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/ba/1aed4e2ea2443d76cec241b96be4ec990852ec b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/ba/1aed4e2ea2443d76cec241b96be4ec990852ec similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/ba/1aed4e2ea2443d76cec241b96be4ec990852ec rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/ba/1aed4e2ea2443d76cec241b96be4ec990852ec diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/c1/0d10b7e655b3dab1f53176db57c8219a5488d6 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/c4/b38c3e1395393f75bbbc2ed10c7eeb577d3b64 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/f5/05ec9b5c7a45a10259c1dda7f18434e5d55940 diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/info/commit-graph b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/info/commit-graph similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/info/commit-graph rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/info/commit-graph diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.bitmap b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.bitmap similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.bitmap rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.bitmap diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.idx b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.idx similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.idx rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.idx diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.pack b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.pack similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.pack rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/objects/pack/pack-a2f7ad943b3d857eb3ebdb4b35eeef38f63cf5d2.pack diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/packed-refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/packed-refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/packed-refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/packed-refs diff --git a/integrations/gitea-repositories-meta/user2/repo2.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo2.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo2.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/config diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/description diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/info/refs diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/02/15cbe13d2695a2c3464ab5e59f47f37c3ff5d5 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/02/15cbe13d2695a2c3464ab5e59f47f37c3ff5d5 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/02/15cbe13d2695a2c3464ab5e59f47f37c3ff5d5 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/02/15cbe13d2695a2c3464ab5e59f47f37c3ff5d5 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/05/81d7edf45206787ff93956ea892e8a2ae77604 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/05/81d7edf45206787ff93956ea892e8a2ae77604 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/05/81d7edf45206787ff93956ea892e8a2ae77604 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/05/81d7edf45206787ff93956ea892e8a2ae77604 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/1b/271d83842d348b1ee71d8e6ead400aaeb4d1b5 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/1b/271d83842d348b1ee71d8e6ead400aaeb4d1b5 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/1b/271d83842d348b1ee71d8e6ead400aaeb4d1b5 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/1b/271d83842d348b1ee71d8e6ead400aaeb4d1b5 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/29/5ba6ac57fdd46f62a51272f40e60b6dea697b2 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/29/5ba6ac57fdd46f62a51272f40e60b6dea697b2 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/29/5ba6ac57fdd46f62a51272f40e60b6dea697b2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/29/5ba6ac57fdd46f62a51272f40e60b6dea697b2 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/2c/ec0f7069ed09d934e904c49f414d8bdf818ce4 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/2c/ec0f7069ed09d934e904c49f414d8bdf818ce4 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/2c/ec0f7069ed09d934e904c49f414d8bdf818ce4 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/2c/ec0f7069ed09d934e904c49f414d8bdf818ce4 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/41/4a282859758ba7b159bfbd9c2b193eb8f135ee b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/41/4a282859758ba7b159bfbd9c2b193eb8f135ee similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/41/4a282859758ba7b159bfbd9c2b193eb8f135ee rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/41/4a282859758ba7b159bfbd9c2b193eb8f135ee diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/80/8038d2f71b0ab020991439cffd24309c7bc530 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/80/8038d2f71b0ab020991439cffd24309c7bc530 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/80/8038d2f71b0ab020991439cffd24309c7bc530 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/80/8038d2f71b0ab020991439cffd24309c7bc530 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/83/70977f63979e140b6b58992b1fdb4098b24cd9 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/83/70977f63979e140b6b58992b1fdb4098b24cd9 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/83/70977f63979e140b6b58992b1fdb4098b24cd9 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/83/70977f63979e140b6b58992b1fdb4098b24cd9 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/8c/e1dee41e1a3700819a9a309f275f8dc7b7e0b6 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/8c/e1dee41e1a3700819a9a309f275f8dc7b7e0b6 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/8c/e1dee41e1a3700819a9a309f275f8dc7b7e0b6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/8c/e1dee41e1a3700819a9a309f275f8dc7b7e0b6 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/ba/3aeafe10402c6b29535a58d91def7e43638d9d b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/ba/3aeafe10402c6b29535a58d91def7e43638d9d similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/ba/3aeafe10402c6b29535a58d91def7e43638d9d rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/ba/3aeafe10402c6b29535a58d91def7e43638d9d diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/c5/0ac6b9e25abb8200bb377755367d7265c581cf b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/c5/0ac6b9e25abb8200bb377755367d7265c581cf similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/c5/0ac6b9e25abb8200bb377755367d7265c581cf rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/c5/0ac6b9e25abb8200bb377755367d7265c581cf diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/db/89c972fc57862eae378f45b74aca228037d415 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/db/89c972fc57862eae378f45b74aca228037d415 similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/db/89c972fc57862eae378f45b74aca228037d415 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/db/89c972fc57862eae378f45b74aca228037d415 diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user2/repo20.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/repo20.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/repo20.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/HEAD diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/config diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/description diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/info/refs diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/14/c42687126acae9d1ad41d7bdb528f811065a6a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/14/c42687126acae9d1ad41d7bdb528f811065a6a similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/14/c42687126acae9d1ad41d7bdb528f811065a6a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/14/c42687126acae9d1ad41d7bdb528f811065a6a diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/1d/5e00f305a7ca6a8a94e65456820a6d260adab8 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/1d/5e00f305a7ca6a8a94e65456820a6d260adab8 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/1d/5e00f305a7ca6a8a94e65456820a6d260adab8 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/1d/5e00f305a7ca6a8a94e65456820a6d260adab8 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/28/d579e4920fbf4f66e71dab3e779d9fbf41422a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/28/d579e4920fbf4f66e71dab3e779d9fbf41422a similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/28/d579e4920fbf4f66e71dab3e779d9fbf41422a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/28/d579e4920fbf4f66e71dab3e779d9fbf41422a diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/810dbf6b96afaa8c5f69a8b6ec1dabfca7368b b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/810dbf6b96afaa8c5f69a8b6ec1dabfca7368b similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/810dbf6b96afaa8c5f69a8b6ec1dabfca7368b rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/810dbf6b96afaa8c5f69a8b6ec1dabfca7368b diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/a73c3499bff049a352b4e265575373e964b89a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/a73c3499bff049a352b4e265575373e964b89a similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/a73c3499bff049a352b4e265575373e964b89a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/a73c3499bff049a352b4e265575373e964b89a diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/c6084110205f98174c4f1ec7e78cb21a15dfc2 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/c6084110205f98174c4f1ec7e78cb21a15dfc2 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/3a/c6084110205f98174c4f1ec7e78cb21a15dfc2 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/3a/c6084110205f98174c4f1ec7e78cb21a15dfc2 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/56/92bcf9f7c9eacb1ad68442161f2573877f96f4 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/56/92bcf9f7c9eacb1ad68442161f2573877f96f4 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/56/92bcf9f7c9eacb1ad68442161f2573877f96f4 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/56/92bcf9f7c9eacb1ad68442161f2573877f96f4 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/6d/0c79ce3401c67d1ad522e61c47083a9fdee16c b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/6d/0c79ce3401c67d1ad522e61c47083a9fdee16c similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/6d/0c79ce3401c67d1ad522e61c47083a9fdee16c rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/6d/0c79ce3401c67d1ad522e61c47083a9fdee16c diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/a9/a61830fbf4e84999d3b20cf178954366701fe5 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/a9/a61830fbf4e84999d3b20cf178954366701fe5 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/a9/a61830fbf4e84999d3b20cf178954366701fe5 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/a9/a61830fbf4e84999d3b20cf178954366701fe5 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/eb/f146f803fccbc1471ef01d8fa0fe12c14e61a5 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/eb/f146f803fccbc1471ef01d8fa0fe12c14e61a5 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/eb/f146f803fccbc1471ef01d8fa0fe12c14e61a5 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/eb/f146f803fccbc1471ef01d8fa0fe12c14e61a5 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/ee/9686cb562f492f64381bff7f298b2a1c67a141 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/ee/9686cb562f492f64381bff7f298b2a1c67a141 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/ee/9686cb562f492f64381bff7f298b2a1c67a141 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/ee/9686cb562f492f64381bff7f298b2a1c67a141 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/f4/02ff67c0b3161c3988dbf6188e6e0df257fd75 b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/f4/02ff67c0b3161c3988dbf6188e6e0df257fd75 similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/f4/02ff67c0b3161c3988dbf6188e6e0df257fd75 rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/f4/02ff67c0b3161c3988dbf6188e6e0df257fd75 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/GrรผรŸen b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/GrรผรŸen similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/GrรผรŸen rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/GrรผรŸen diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/Plus+Is+Not+Space similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/Plus+Is+Not+Space diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ะ“ะปะฐะฒะฝะฐัะ’ะตั‚ะบะฐ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ะ“ะปะฐะฒะฝะฐัะ’ะตั‚ะบะฐ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ะ“ะปะฐะฒะฝะฐัะ’ะตั‚ะบะฐ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ะ“ะปะฐะฒะฝะฐัะ’ะตั‚ะบะฐ diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ะฐ/ะฑ/ะฒ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ะฐ/ะฑ/ะฒ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ะฐ/ะฑ/ะฒ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ะฐ/ะฑ/ะฒ diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ใƒ–ใƒฉใƒณใƒ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ใƒ–ใƒฉใƒณใƒ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/ใƒ–ใƒฉใƒณใƒ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/heads/ใƒ–ใƒฉใƒณใƒ diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ะ/ไบบ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ะ/ไบบ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ะ/ไบบ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ะ/ไบบ diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ะขัะณ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ะขัะณ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ะขัะณ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ะขัะณ diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ใ‚ฟใ‚ฐ b/integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ใ‚ฟใ‚ฐ similarity index 100% rename from integrations/gitea-repositories-meta/user2/utf8.git/refs/tags/ใ‚ฟใ‚ฐ rename to integrations/gitea-integration-sqlite/gitea-repositories/user2/utf8.git/refs/tags/ใ‚ฟใ‚ฐ diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/HEAD diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/config diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/description diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/info/refs diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user27/repo49.git/refs/heads/test/archive b/integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/refs/heads/test/archive similarity index 100% rename from integrations/gitea-repositories-meta/user27/repo49.git/refs/heads/test/archive rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/repo49.git/refs/heads/test/archive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/HEAD diff --git a/integrations/gitea-repositories-meta/user27/template1.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/config diff --git a/integrations/gitea-repositories-meta/user27/template1.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/description diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user27/template1.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user27/template1.git/info/refs b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/info/refs similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/info/refs rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/info/refs diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/47/34b1f84a367fa1b81c31aa4234a5bad11cafa3 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/4d/31f3a12656368a8d9180f431d40d0fc408be2d diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/51/f84af231345367fd5d61ceb89efb3b6d757061 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/79/3aa682b06ae032641abf70c5dfeade28c07c52 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/aa/cbdfe9e1c4b47f60abe81849045fa4e96f1d75 diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/dd/392e939ea4936b2459219c9c9a1f25547ccaeb diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/f2/8eeca3df7614fd4f10c1030f13feb418ef3c6f diff --git a/integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/info/packs similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/objects/info/packs rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/objects/info/packs diff --git a/integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user27/template1.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user27/template1.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/HEAD diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/config diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/description diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/post-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/post-receive similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/post-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/post-receive diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/post-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/post-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/post-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/post-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/pre-receive b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/pre-receive similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/pre-receive rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/pre-receive diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/pre-receive.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/pre-receive.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/pre-receive.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/pre-receive.d/gitea diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/update b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/update similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/update rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/update diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/hooks/update.d/gitea b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/update.d/gitea similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/hooks/update.d/gitea rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/hooks/update.d/gitea diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/20/ade30d25e0ecaeec84e7f542a8456900858240 b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/20/ade30d25e0ecaeec84e7f542a8456900858240 similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/20/ade30d25e0ecaeec84e7f542a8456900858240 rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/20/ade30d25e0ecaeec84e7f542a8456900858240 diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/27/74debeea6dc742cc4971a92db0e08b95b60588 b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/27/74debeea6dc742cc4971a92db0e08b95b60588 similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/27/74debeea6dc742cc4971a92db0e08b95b60588 rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/27/74debeea6dc742cc4971a92db0e08b95b60588 diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/2a/47ca4b614a9f5a43abbd5ad851a54a616ffee6 b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/2a/47ca4b614a9f5a43abbd5ad851a54a616ffee6 similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/2a/47ca4b614a9f5a43abbd5ad851a54a616ffee6 rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/2a/47ca4b614a9f5a43abbd5ad851a54a616ffee6 diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/2f/9b22fd3159a43b7b4e5dd806fcd544edf8716f b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/2f/9b22fd3159a43b7b4e5dd806fcd544edf8716f similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/2f/9b22fd3159a43b7b4e5dd806fcd544edf8716f rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/2f/9b22fd3159a43b7b4e5dd806fcd544edf8716f diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/d2/2b4d4daa5be07329fcef6ed458f00cf3392da0 b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/d2/2b4d4daa5be07329fcef6ed458f00cf3392da0 similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/d2/2b4d4daa5be07329fcef6ed458f00cf3392da0 rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/d2/2b4d4daa5be07329fcef6ed458f00cf3392da0 diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/d5/6a3073c1dbb7b15963110a049d50cdb5db99fc b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/d5/6a3073c1dbb7b15963110a049d50cdb5db99fc similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/d5/6a3073c1dbb7b15963110a049d50cdb5db99fc rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/d5/6a3073c1dbb7b15963110a049d50cdb5db99fc diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/ec/f0db3c1ec806522de4b491fb9a3c7457398c61 b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/ec/f0db3c1ec806522de4b491fb9a3c7457398c61 similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/ec/f0db3c1ec806522de4b491fb9a3c7457398c61 rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/ec/f0db3c1ec806522de4b491fb9a3c7457398c61 diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/objects/ee/16d127df463aa491e08958120f2108b02468df b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/ee/16d127df463aa491e08958120f2108b02468df similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/objects/ee/16d127df463aa491e08958120f2108b02468df rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/objects/ee/16d127df463aa491e08958120f2108b02468df diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/refs/heads/master diff --git a/integrations/gitea-repositories-meta/user3/repo3.git/refs/heads/test_branch b/integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/refs/heads/test_branch similarity index 100% rename from integrations/gitea-repositories-meta/user3/repo3.git/refs/heads/test_branch rename to integrations/gitea-integration-sqlite/gitea-repositories/user3/repo3.git/refs/heads/test_branch diff --git a/integrations/gitea-repositories-meta/user30/empty.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user30/empty.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user30/empty.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user30/empty.git/HEAD diff --git a/integrations/gitea-repositories-meta/user30/empty.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user30/empty.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user30/empty.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user30/empty.git/config diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/HEAD b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/HEAD similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/HEAD rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/HEAD diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/config b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/config similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/config rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/config diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/description b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/description similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/description rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/description diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/info/exclude b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/info/exclude similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/info/exclude rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/info/exclude diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/objects/16/dfebd1ed3905d78d7e061e945fc9c34afe4e81 b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/16/dfebd1ed3905d78d7e061e945fc9c34afe4e81 similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/objects/16/dfebd1ed3905d78d7e061e945fc9c34afe4e81 rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/16/dfebd1ed3905d78d7e061e945fc9c34afe4e81 diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/objects/c1/202ad022ae7d3a6d2474dc76d5a0c8e87cdc0f b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/c1/202ad022ae7d3a6d2474dc76d5a0c8e87cdc0f similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/objects/c1/202ad022ae7d3a6d2474dc76d5a0c8e87cdc0f rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/c1/202ad022ae7d3a6d2474dc76d5a0c8e87cdc0f diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/objects/c7/cd3cd144e6d23c9d6f3d07e52b2c1a956e0338 b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/c7/cd3cd144e6d23c9d6f3d07e52b2c1a956e0338 similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/objects/c7/cd3cd144e6d23c9d6f3d07e52b2c1a956e0338 rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/objects/c7/cd3cd144e6d23c9d6f3d07e52b2c1a956e0338 diff --git a/integrations/gitea-repositories-meta/user5/repo4.git/refs/heads/master b/integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/refs/heads/master similarity index 100% rename from integrations/gitea-repositories-meta/user5/repo4.git/refs/heads/master rename to integrations/gitea-integration-sqlite/gitea-repositories/user5/repo4.git/refs/heads/master diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini similarity index 91% rename from integrations/sqlite.ini.tmpl rename to integrations/sqlite.ini index fa57e1aa9..dd340a668 100644 --- a/integrations/sqlite.ini.tmpl +++ b/integrations/sqlite.ini @@ -6,13 +6,11 @@ DB_TYPE = sqlite3 PATH = integrations/gitea-integration-sqlite/gitea.db [indexer] +ISSUE_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve +ISSUE_INDEXER_QUEUE_DIR = integrations/gitea-integration-sqlite/indexers/issues.queue REPO_INDEXER_ENABLED = true REPO_INDEXER_PATH = integrations/gitea-integration-sqlite/indexers/repos.bleve -[queue.issue_indexer] -PATH = integrations/gitea-integration-sqlite/indexers/issues.bleve -DATADIR = integrations/gitea-integration-sqlite/indexers/issues.queue - [queue] TYPE = immediate @@ -23,7 +21,7 @@ TYPE = immediate TYPE = immediate [repository] -ROOT = {{REPO_TEST_DIR}}integrations/gitea-integration-sqlite/gitea-repositories +ROOT = integrations/gitea-integration-sqlite/gitea-repositories [repository.local] LOCAL_COPY_PATH = integrations/gitea-integration-sqlite/tmp/local-repo @@ -81,7 +79,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-sqlite/data/sessions [log] MODE = test,file -ROOT_PATH = {{REPO_TEST_DIR}}sqlite-log +ROOT_PATH = sqlite-log ROUTER = , XORM = file ENABLE_SSH_LOG = true diff --git a/jest.config.js b/jest.config.js index d24333aa3..34d47acc4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,7 @@ export default { rootDir: 'web_src', setupFilesAfterEnv: ['jest-extended/all'], - testEnvironment: '@happy-dom/jest-environment', + testEnvironment: 'jest-environment-jsdom', testMatch: ['/**/*.test.js'], testTimeout: 20000, transform: { diff --git a/models/action.go b/models/activities/action.go similarity index 94% rename from models/action.go rename to models/activities/action.go index 0d0c16d42..07d79b96f 100644 --- a/models/action.go +++ b/models/activities/action.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities import ( "context" @@ -98,7 +98,14 @@ func (a *Action) TableIndices() []*schemas.Index { actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType) actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted") - return []*schemas.Index{actUserIndex, repoIndex} + indices := []*schemas.Index{actUserIndex, repoIndex} + if setting.Database.UsePostgreSQL { + cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType) + cudIndex.AddColumn("created_unix", "user_id", "is_deleted") + indices = append(indices, cudIndex) + } + + return indices } // GetOpType gets the ActionType of this action. @@ -211,21 +218,6 @@ func (a *Action) GetRepoLink() string { return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName())) } -// GetRepositoryFromMatch returns a *repo_model.Repository from a username and repo strings -func GetRepositoryFromMatch(ownerName, repoName string) (*repo_model.Repository, error) { - var err error - refRepo, err := repo_model.GetRepositoryByOwnerAndName(ownerName, repoName) - if err != nil { - if repo_model.IsErrRepoNotExist(err) { - log.Warn("Repository referenced in commit but does not exist: %v", err) - return nil, err - } - log.Error("repo_model.GetRepositoryByOwnerAndName: %v", err) - return nil, err - } - return refRepo, nil -} - // GetCommentLink returns link to action comment. func (a *Action) GetCommentLink() string { return a.getCommentLink(db.DefaultContext) @@ -275,7 +267,7 @@ func (a *Action) GetRefLink() string { return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) case strings.HasPrefix(a.RefName, git.TagPrefix): return a.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.TagPrefix)) - case len(a.RefName) == 40 && git.SHAPattern.MatchString(a.RefName): + case len(a.RefName) == 40 && git.IsValidSHAPattern(a.RefName): return a.GetRepoLink() + "/src/commit/" + a.RefName default: // FIXME: we will just assume it's a branch - this was the old way - at some point we may want to enforce that there is always a ref here. @@ -373,7 +365,8 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, error) { return actions, nil } -func activityReadable(user, doer *user_model.User) bool { +// ActivityReadable return whether doer can read activities of user +func ActivityReadable(user, doer *user_model.User) bool { return !user.KeepActivityPrivate || doer != nil && (doer.IsAdmin || user.ID == doer.ID) } @@ -607,3 +600,23 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error { Delete(&Action{}) return err } + +// CountActionCreatedUnixString count actions where created_unix is an empty string +func CountActionCreatedUnixString() (int64, error) { + if setting.Database.UseSQLite3 { + return db.GetEngine(db.DefaultContext).Where(`created_unix = ""`).Count(new(Action)) + } + return 0, nil +} + +// FixActionCreatedUnixString set created_unix to zero if it is an empty string +func FixActionCreatedUnixString() (int64, error) { + if setting.Database.UseSQLite3 { + res, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`) + if err != nil { + return 0, err + } + return res.RowsAffected() + } + return 0, nil +} diff --git a/models/action_list.go b/models/activities/action_list.go similarity index 99% rename from models/action_list.go rename to models/activities/action_list.go index d585ef0fc..16fb4bac8 100644 --- a/models/action_list.go +++ b/models/activities/action_list.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities import ( "context" diff --git a/models/action_test.go b/models/activities/action_test.go similarity index 76% rename from models/action_test.go rename to models/activities/action_test.go index 5c61736a6..83fd9ee38 100644 --- a/models/action_test.go +++ b/models/activities/action_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities_test import ( "path" "testing" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -21,7 +22,7 @@ func TestAction_GetRepoPath(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - action := &Action{RepoID: repo.ID} + action := &activities_model.Action{RepoID: repo.ID} assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath()) } @@ -29,7 +30,7 @@ func TestAction_GetRepoLink(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - action := &Action{RepoID: repo.ID} + action := &activities_model.Action{RepoID: repo.ID} setting.AppSubURL = "/suburl" expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) assert.Equal(t, expected, action.GetRepoLink()) @@ -40,7 +41,7 @@ func TestGetFeeds(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: true, @@ -53,7 +54,7 @@ func TestGetFeeds(t *testing.T) { assert.EqualValues(t, user.ID, actions[0].UserID) } - actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: false, @@ -70,7 +71,7 @@ func TestGetFeedsForRepos(t *testing.T) { pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) // private repo & no login - actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedRepo: privRepo, IncludePrivate: true, }) @@ -78,7 +79,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Len(t, actions, 0) // public repo & no login - actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedRepo: pubRepo, IncludePrivate: true, }) @@ -86,7 +87,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Len(t, actions, 1) // private repo and login - actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedRepo: privRepo, IncludePrivate: true, Actor: user, @@ -95,7 +96,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Len(t, actions, 1) // public repo & login - actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedRepo: pubRepo, IncludePrivate: true, Actor: user, @@ -110,7 +111,7 @@ func TestGetFeeds2(t *testing.T) { org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: org, Actor: user, IncludePrivate: true, @@ -124,7 +125,7 @@ func TestGetFeeds2(t *testing.T) { assert.EqualValues(t, org.ID, actions[0].UserID) } - actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: org, Actor: user, IncludePrivate: false, @@ -171,40 +172,40 @@ func TestActivityReadable(t *testing.T) { result: true, }} for _, test := range tt { - assert.Equal(t, test.result, activityReadable(test.user, test.doer), test.desc) + assert.Equal(t, test.result, activities_model.ActivityReadable(test.user, test.doer), test.desc) } } func TestNotifyWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - action := &Action{ + action := &activities_model.Action{ ActUserID: 8, RepoID: 1, - OpType: ActionStarRepo, + OpType: activities_model.ActionStarRepo, } - assert.NoError(t, NotifyWatchers(action)) + assert.NoError(t, activities_model.NotifyWatchers(action)) // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ActUserID: action.ActUserID, UserID: 8, RepoID: action.RepoID, OpType: action.OpType, }) - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ActUserID: action.ActUserID, UserID: 1, RepoID: action.RepoID, OpType: action.OpType, }) - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ActUserID: action.ActUserID, UserID: 4, RepoID: action.RepoID, OpType: action.OpType, }) - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ActUserID: action.ActUserID, UserID: 11, RepoID: action.RepoID, @@ -215,12 +216,12 @@ func TestNotifyWatchers(t *testing.T) { func TestGetFeedsCorrupted(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ID: 8, RepoID: 1700, }) - actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: true, @@ -235,12 +236,12 @@ func TestConsistencyUpdateAction(t *testing.T) { } assert.NoError(t, unittest.PrepareTestDatabase()) id := 8 - unittest.AssertExistsAndLoadBean(t, &Action{ + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ID: int64(id), }) _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) assert.NoError(t, err) - actions := make([]*Action, 0, 1) + actions := make([]*activities_model.Action, 0, 1) // // XORM returns an error when created_unix is a string // @@ -251,17 +252,17 @@ func TestConsistencyUpdateAction(t *testing.T) { // // Get rid of incorrectly set created_unix // - count, err := CountActionCreatedUnixString() + count, err := activities_model.CountActionCreatedUnixString() assert.NoError(t, err) assert.EqualValues(t, 1, count) - count, err = FixActionCreatedUnixString() + count, err = activities_model.FixActionCreatedUnixString() assert.NoError(t, err) assert.EqualValues(t, 1, count) - count, err = CountActionCreatedUnixString() + count, err = activities_model.CountActionCreatedUnixString() assert.NoError(t, err) assert.EqualValues(t, 0, count) - count, err = FixActionCreatedUnixString() + count, err = activities_model.FixActionCreatedUnixString() assert.NoError(t, err) assert.EqualValues(t, 0, count) @@ -269,5 +270,5 @@ func TestConsistencyUpdateAction(t *testing.T) { // XORM must be happy now // assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) - unittest.CheckConsistencyFor(t, &Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } diff --git a/models/activities/main_test.go b/models/activities/main_test.go new file mode 100644 index 000000000..0a87f4760 --- /dev/null +++ b/models/activities/main_test.go @@ -0,0 +1,20 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activities_test + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: filepath.Join("..", ".."), + }) +} diff --git a/models/notification.go b/models/activities/notification.go similarity index 98% rename from models/notification.go rename to models/activities/notification.go index fdc4ffad1..88776db42 100644 --- a/models/notification.go +++ b/models/activities/notification.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities import ( "context" @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -267,10 +268,10 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n return err } - if issue.IsPull && !CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypePullRequests) { + if issue.IsPull && !access_model.CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypePullRequests) { continue } - if !issue.IsPull && !CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypeIssues) { + if !issue.IsPull && !access_model.CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypeIssues) { continue } diff --git a/models/notification_test.go b/models/activities/notification_test.go similarity index 52% rename from models/notification_test.go rename to models/activities/notification_test.go index 340fb4337..4ee16af07 100644 --- a/models/notification_test.go +++ b/models/activities/notification_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities_test import ( "testing" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" @@ -19,22 +20,22 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) + assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) // User 9 is inactive, thus notifications for user 1 and 4 are created - notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}) - assert.Equal(t, NotificationStatusUnread, notf.Status) + notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 1, IssueID: issue.ID}) + assert.Equal(t, activities_model.NotificationStatusUnread, notf.Status) unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) - notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}) - assert.Equal(t, NotificationStatusUnread, notf.Status) + notf = unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 4, IssueID: issue.ID}) + assert.Equal(t, activities_model.NotificationStatusUnread, notf.Status) } func TestNotificationsForUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - statuses := []NotificationStatus{NotificationStatusRead, NotificationStatusUnread} - notfs, err := NotificationsForUser(db.DefaultContext, user, statuses, 1, 10) + statuses := []activities_model.NotificationStatus{activities_model.NotificationStatusRead, activities_model.NotificationStatusUnread} + notfs, err := activities_model.NotificationsForUser(db.DefaultContext, user, statuses, 1, 10) assert.NoError(t, err) if assert.Len(t, notfs, 3) { assert.EqualValues(t, 5, notfs[0].ID) @@ -48,7 +49,7 @@ func TestNotificationsForUser(t *testing.T) { func TestNotification_GetRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) + notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) repo, err := notf.GetRepo() assert.NoError(t, err) assert.Equal(t, repo, notf.Repository) @@ -57,7 +58,7 @@ func TestNotification_GetRepo(t *testing.T) { func TestNotification_GetIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) + notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) issue, err := notf.GetIssue() assert.NoError(t, err) assert.Equal(t, issue, notf.Issue) @@ -67,11 +68,11 @@ func TestNotification_GetIssue(t *testing.T) { func TestGetNotificationCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - cnt, err := GetNotificationCount(db.DefaultContext, user, NotificationStatusRead) + cnt, err := activities_model.GetNotificationCount(db.DefaultContext, user, activities_model.NotificationStatusRead) assert.NoError(t, err) assert.EqualValues(t, 0, cnt) - cnt, err = GetNotificationCount(db.DefaultContext, user, NotificationStatusUnread) + cnt, err = activities_model.GetNotificationCount(db.DefaultContext, user, activities_model.NotificationStatusUnread) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) } @@ -80,15 +81,15 @@ func TestSetNotificationStatus(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) notf := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusRead}) - _, err := SetNotificationStatus(notf.ID, user, NotificationStatusPinned) + &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) + _, err := activities_model.SetNotificationStatus(notf.ID, user, activities_model.NotificationStatusPinned) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, - &Notification{ID: notf.ID, Status: NotificationStatusPinned}) + &activities_model.Notification{ID: notf.ID, Status: activities_model.NotificationStatusPinned}) - _, err = SetNotificationStatus(1, user, NotificationStatusRead) + _, err = activities_model.SetNotificationStatus(1, user, activities_model.NotificationStatusRead) assert.Error(t, err) - _, err = SetNotificationStatus(unittest.NonexistentID, user, NotificationStatusRead) + _, err = activities_model.SetNotificationStatus(unittest.NonexistentID, user, activities_model.NotificationStatusRead) assert.Error(t, err) } @@ -96,16 +97,16 @@ func TestUpdateNotificationStatuses(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) notfUnread := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusUnread}) + &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusUnread}) notfRead := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusRead}) + &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) notfPinned := unittest.AssertExistsAndLoadBean(t, - &Notification{UserID: user.ID, Status: NotificationStatusPinned}) - assert.NoError(t, UpdateNotificationStatuses(user, NotificationStatusUnread, NotificationStatusRead)) + &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusPinned}) + assert.NoError(t, activities_model.UpdateNotificationStatuses(user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)) unittest.AssertExistsAndLoadBean(t, - &Notification{ID: notfUnread.ID, Status: NotificationStatusRead}) + &activities_model.Notification{ID: notfUnread.ID, Status: activities_model.NotificationStatusRead}) unittest.AssertExistsAndLoadBean(t, - &Notification{ID: notfRead.ID, Status: NotificationStatusRead}) + &activities_model.Notification{ID: notfRead.ID, Status: activities_model.NotificationStatusRead}) unittest.AssertExistsAndLoadBean(t, - &Notification{ID: notfPinned.ID, Status: NotificationStatusPinned}) + &activities_model.Notification{ID: notfPinned.ID, Status: activities_model.NotificationStatusPinned}) } diff --git a/models/repo_activity.go b/models/activities/repo_activity.go similarity index 98% rename from models/repo_activity.go rename to models/activities/repo_activity.go index 6a3636ab0..684ceee27 100644 --- a/models/repo_activity.go +++ b/models/activities/repo_activity.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities import ( "context" @@ -39,7 +39,7 @@ type ActivityStats struct { ClosedIssues issues_model.IssueList ClosedIssueAuthorCount int64 UnresolvedIssues issues_model.IssueList - PublishedReleases []*Release + PublishedReleases []*repo_model.Release PublishedReleaseAuthorCount int64 Code *git.CodeActivityStats } @@ -344,7 +344,7 @@ func (stats *ActivityStats) FillReleases(repoID int64, fromTime time.Time) error // Published releases list sess := releasesForActivityStatement(repoID, fromTime) sess.OrderBy("release.created_unix DESC") - stats.PublishedReleases = make([]*Release, 0) + stats.PublishedReleases = make([]*repo_model.Release, 0) if err = sess.Find(&stats.PublishedReleases); err != nil { return err } diff --git a/models/statistic.go b/models/activities/statistic.go similarity index 97% rename from models/statistic.go rename to models/activities/statistic.go index ec094b5f5..ea785a3ee 100644 --- a/models/statistic.go +++ b/models/activities/statistic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package activities import ( asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -101,7 +101,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.Oauth = 0 stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) - stats.Counter.Release, _ = e.Count(new(Release)) + stats.Counter.Release, _ = e.Count(new(repo_model.Release)) stats.Counter.AuthSource = auth.CountSources() stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) diff --git a/models/user_heatmap.go b/models/activities/user_heatmap.go similarity index 97% rename from models/user_heatmap.go rename to models/activities/user_heatmap.go index e908837ae..6e76be6c6 100644 --- a/models/user_heatmap.go +++ b/models/activities/user_heatmap.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file.package models -package models +package activities import ( "code.gitea.io/gitea/models/db" @@ -31,7 +31,7 @@ func GetUserHeatmapDataByUserTeam(user *user_model.User, team *organization.Team func getUserHeatmapData(user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { hdata := make([]*UserHeatmapData, 0) - if !activityReadable(user, doer) { + if !ActivityReadable(user, doer) { return hdata, nil } diff --git a/models/user_heatmap_test.go b/models/activities/user_heatmap_test.go similarity index 90% rename from models/user_heatmap_test.go rename to models/activities/user_heatmap_test.go index 1ff7bc6ed..a8a240f79 100644 --- a/models/user_heatmap_test.go +++ b/models/activities/user_heatmap_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file.package models -package models +package activities_test import ( "fmt" "testing" "time" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -73,7 +74,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { } // get the action for comparison - actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ + actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ RequestedUser: user, Actor: doer, IncludePrivate: true, @@ -83,7 +84,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { assert.NoError(t, err) // Get the heatmap and compare - heatmap, err := GetUserHeatmapDataByUser(user, doer) + heatmap, err := activities_model.GetUserHeatmapDataByUser(user, doer) var contributions int for _, hm := range heatmap { contributions += int(hm.Contributions) diff --git a/models/admin/main_test.go b/models/admin/main_test.go index 693b70fbf..23277fe37 100644 --- a/models/admin/main_test.go +++ b/models/admin/main_test.go @@ -2,18 +2,21 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package admin +package admin_test import ( "path/filepath" "testing" "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" + _ "code.gitea.io/gitea/models/activities" + _ "code.gitea.io/gitea/models/perm/access" ) func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ GiteaRootPath: filepath.Join("..", ".."), - FixtureFiles: []string{"notice.yml"}, }) } diff --git a/models/admin/notice_test.go b/models/admin/notice_test.go index b4613db8e..f3767392d 100644 --- a/models/admin/notice_test.go +++ b/models/admin/notice_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package admin +package admin_test import ( "testing" + "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" @@ -14,8 +15,8 @@ import ( ) func TestNotice_TrStr(t *testing.T) { - notice := &Notice{ - Type: NoticeRepository, + notice := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } assert.Equal(t, "admin.notices.type_1", notice.TrStr()) @@ -24,24 +25,24 @@ func TestNotice_TrStr(t *testing.T) { func TestCreateNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - noticeBean := &Notice{ - Type: NoticeRepository, + noticeBean := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } unittest.AssertNotExistsBean(t, noticeBean) - assert.NoError(t, CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) + assert.NoError(t, admin.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) unittest.AssertExistsAndLoadBean(t, noticeBean) } func TestCreateRepositoryNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - noticeBean := &Notice{ - Type: NoticeRepository, + noticeBean := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } unittest.AssertNotExistsBean(t, noticeBean) - assert.NoError(t, CreateRepositoryNotice(noticeBean.Description)) + assert.NoError(t, admin.CreateRepositoryNotice(noticeBean.Description)) unittest.AssertExistsAndLoadBean(t, noticeBean) } @@ -49,20 +50,20 @@ func TestCreateRepositoryNotice(t *testing.T) { func TestCountNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.Equal(t, int64(3), CountNotices()) + assert.Equal(t, int64(3), admin.CountNotices()) } func TestNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notices, err := Notices(1, 2) + notices, err := admin.Notices(1, 2) assert.NoError(t, err) if assert.Len(t, notices, 2) { assert.Equal(t, int64(3), notices[0].ID) assert.Equal(t, int64(2), notices[1].ID) } - notices, err = Notices(2, 2) + notices, err = admin.Notices(2, 2) assert.NoError(t, err) if assert.Len(t, notices, 1) { assert.Equal(t, int64(1), notices[0].ID) @@ -72,45 +73,45 @@ func TestNotices(t *testing.T) { func TestDeleteNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotice(3)) - unittest.AssertNotExistsBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotice(3)) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) } func TestDeleteNotices(t *testing.T) { // delete a non-empty range assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotices(1, 2)) - unittest.AssertNotExistsBean(t, &Notice{ID: 1}) - unittest.AssertNotExistsBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotices(1, 2)) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) } func TestDeleteNotices2(t *testing.T) { // delete an empty range assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotices(3, 2)) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotices(3, 2)) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) } func TestDeleteNoticesByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNoticesByIDs([]int64{1, 3})) - unittest.AssertNotExistsBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertNotExistsBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNoticesByIDs([]int64{1, 3})) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) } diff --git a/models/task.go b/models/admin/task.go similarity index 99% rename from models/task.go rename to models/admin/task.go index 67f04d956..07eb61dec 100644 --- a/models/task.go +++ b/models/admin/task.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package admin import ( "context" diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index 2b9997237..78dc453e0 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -33,7 +33,7 @@ type GPGKey struct { OwnerID int64 `xorm:"INDEX NOT NULL"` KeyID string `xorm:"INDEX CHAR(16) NOT NULL"` PrimaryKeyID string `xorm:"CHAR(16)"` - Content string `xorm:"TEXT NOT NULL"` + Content string `xorm:"MEDIUMTEXT NOT NULL"` CreatedUnix timeutil.TimeStamp `xorm:"created"` ExpiredUnix timeutil.TimeStamp AddedUnix timeutil.TimeStamp @@ -63,6 +63,15 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) { } } +// PaddedKeyID show KeyID padded to 16 characters +func (key *GPGKey) PaddedKeyID() string { + if len(key.KeyID) > 15 { + return key.KeyID + } + zeros := "0000000000000000" + return zeros[0:16-len(key.KeyID)] + key.KeyID +} + // ListGPGKeys returns a list of public keys belongs to given user. func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) { sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid) diff --git a/models/asymkey/ssh_key.go b/models/asymkey/ssh_key.go index 107a29e98..9f95bb5ba 100644 --- a/models/asymkey/ssh_key.go +++ b/models/asymkey/ssh_key.go @@ -41,7 +41,7 @@ type PublicKey struct { OwnerID int64 `xorm:"INDEX NOT NULL"` Name string `xorm:"NOT NULL"` Fingerprint string `xorm:"INDEX NOT NULL"` - Content string `xorm:"TEXT NOT NULL"` + Content string `xorm:"MEDIUMTEXT NOT NULL"` Mode perm.AccessMode `xorm:"NOT NULL DEFAULT 2"` Type KeyType `xorm:"NOT NULL DEFAULT 1"` LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` diff --git a/models/auth/main_test.go b/models/auth/main_test.go index ccbdd4e81..5d52e963b 100644 --- a/models/auth/main_test.go +++ b/models/auth/main_test.go @@ -2,24 +2,22 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package auth_test import ( "path/filepath" "testing" "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" + _ "code.gitea.io/gitea/models/activities" + _ "code.gitea.io/gitea/models/auth" + _ "code.gitea.io/gitea/models/perm/access" ) func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ GiteaRootPath: filepath.Join("..", ".."), - FixtureFiles: []string{ - "login_source.yml", - "oauth2_application.yml", - "oauth2_authorization_code.yml", - "oauth2_grant.yml", - "webauthn_credential.yml", - }, }) } diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index 2a74f3999..3b2ba8c8f 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package auth_test import ( "testing" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" @@ -17,23 +18,23 @@ import ( func TestOAuth2Application_GenerateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) + app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) secret, err := app.GenerateClientSecret() assert.NoError(t, err) assert.True(t, len(secret) > 0) - unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1, ClientSecret: app.ClientSecret}) + unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret}) } func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) { assert.NoError(b, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1}) + app := unittest.AssertExistsAndLoadBean(b, &auth_model.OAuth2Application{ID: 1}) for i := 0; i < b.N; i++ { _, _ = app.GenerateClientSecret() } } func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { - app := &OAuth2Application{ + app := &auth_model.OAuth2Application{ RedirectURIs: []string{"a", "b", "c"}, } assert.True(t, app.ContainsRedirectURI("a")) @@ -44,7 +45,7 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { func TestOAuth2Application_ValidateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) + app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) secret, err := app.GenerateClientSecret() assert.NoError(t, err) assert.True(t, app.ValidateClientSecret([]byte(secret))) @@ -53,31 +54,31 @@ func TestOAuth2Application_ValidateClientSecret(t *testing.T) { func TestGetOAuth2ApplicationByClientID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app, err := GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138") + app, err := auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138") assert.NoError(t, err) assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID) - app, err = GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id") + app, err = auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id") assert.Error(t, err) assert.Nil(t, app) } func TestCreateOAuth2Application(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app, err := CreateOAuth2Application(db.DefaultContext, CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) + app, err := auth_model.CreateOAuth2Application(db.DefaultContext, auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) assert.NoError(t, err) assert.Equal(t, "newapp", app.Name) assert.Len(t, app.ClientID, 36) - unittest.AssertExistsAndLoadBean(t, &OAuth2Application{Name: "newapp"}) + unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{Name: "newapp"}) } func TestOAuth2Application_TableName(t *testing.T) { - assert.Equal(t, "oauth2_application", new(OAuth2Application).TableName()) + assert.Equal(t, "oauth2_application", new(auth_model.OAuth2Application).TableName()) } func TestOAuth2Application_GetGrantByUserID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) + app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) grant, err := app.GetGrantByUserID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, int64(1), grant.UserID) @@ -89,7 +90,7 @@ func TestOAuth2Application_GetGrantByUserID(t *testing.T) { func TestOAuth2Application_CreateGrant(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) + app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) grant, err := app.CreateGrant(db.DefaultContext, 2, "") assert.NoError(t, err) assert.NotNil(t, grant) @@ -102,26 +103,26 @@ func TestOAuth2Application_CreateGrant(t *testing.T) { func TestGetOAuth2GrantByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant, err := GetOAuth2GrantByID(db.DefaultContext, 1) + grant, err := auth_model.GetOAuth2GrantByID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, int64(1), grant.ID) - grant, err = GetOAuth2GrantByID(db.DefaultContext, 34923458) + grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, 34923458) assert.NoError(t, err) assert.Nil(t, grant) } func TestOAuth2Grant_IncreaseCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1}) + grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 1}) assert.NoError(t, grant.IncreaseCounter(db.DefaultContext)) assert.Equal(t, int64(2), grant.Counter) - unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 2}) + unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 2}) } func TestOAuth2Grant_ScopeContains(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"}) + grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Scope: "openid profile"}) assert.True(t, grant.ScopeContains("openid")) assert.True(t, grant.ScopeContains("profile")) assert.False(t, grant.ScopeContains("profil")) @@ -130,7 +131,7 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) { func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1}) + grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1}) code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") assert.NoError(t, err) assert.NotNil(t, code) @@ -138,46 +139,46 @@ func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { } func TestOAuth2Grant_TableName(t *testing.T) { - assert.Equal(t, "oauth2_grant", new(OAuth2Grant).TableName()) + assert.Equal(t, "oauth2_grant", new(auth_model.OAuth2Grant).TableName()) } func TestGetOAuth2GrantsByUserID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - result, err := GetOAuth2GrantsByUserID(db.DefaultContext, 1) + result, err := auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 1) assert.NoError(t, err) assert.Len(t, result, 1) assert.Equal(t, int64(1), result[0].ID) assert.Equal(t, result[0].ApplicationID, result[0].Application.ID) - result, err = GetOAuth2GrantsByUserID(db.DefaultContext, 34134) + result, err = auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 34134) assert.NoError(t, err) assert.Empty(t, result) } func TestRevokeOAuth2Grant(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, RevokeOAuth2Grant(db.DefaultContext, 1, 1)) - unittest.AssertNotExistsBean(t, &OAuth2Grant{ID: 1, UserID: 1}) + assert.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1)) + unittest.AssertNotExistsBean(t, &auth_model.OAuth2Grant{ID: 1, UserID: 1}) } //////////////////// Authorization Code func TestGetOAuth2AuthorizationByCode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - code, err := GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode") + code, err := auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode") assert.NoError(t, err) assert.NotNil(t, code) assert.Equal(t, "authcode", code.Code) assert.Equal(t, int64(1), code.ID) - code, err = GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist") + code, err = auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist") assert.NoError(t, err) assert.Nil(t, code) } func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { // test plain - code := &OAuth2AuthorizationCode{ + code := &auth_model.OAuth2AuthorizationCode{ CodeChallengeMethod: "plain", CodeChallenge: "test123", } @@ -185,7 +186,7 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { assert.False(t, code.ValidateCodeChallenge("ierwgjoergjio")) // test S256 - code = &OAuth2AuthorizationCode{ + code = &auth_model.OAuth2AuthorizationCode{ CodeChallengeMethod: "S256", CodeChallenge: "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", } @@ -193,14 +194,14 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { assert.False(t, code.ValidateCodeChallenge("wiogjerogorewngoenrgoiuenorg")) // test unknown - code = &OAuth2AuthorizationCode{ + code = &auth_model.OAuth2AuthorizationCode{ CodeChallengeMethod: "monkey", CodeChallenge: "foiwgjioriogeiogjerger", } assert.False(t, code.ValidateCodeChallenge("foiwgjioriogeiogjerger")) // test no code challenge - code = &OAuth2AuthorizationCode{ + code = &auth_model.OAuth2AuthorizationCode{ CodeChallengeMethod: "", CodeChallenge: "foierjiogerogerg", } @@ -208,7 +209,7 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { } func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { - code := &OAuth2AuthorizationCode{ + code := &auth_model.OAuth2AuthorizationCode{ RedirectURI: "https://example.com/callback", Code: "thecode", } @@ -224,11 +225,11 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) + code := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) assert.NoError(t, code.Invalidate(db.DefaultContext)) - unittest.AssertNotExistsBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) + unittest.AssertNotExistsBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) } func TestOAuth2AuthorizationCode_TableName(t *testing.T) { - assert.Equal(t, "oauth2_authorization_code", new(OAuth2AuthorizationCode).TableName()) + assert.Equal(t, "oauth2_authorization_code", new(auth_model.OAuth2AuthorizationCode).TableName()) } diff --git a/models/auth/source_test.go b/models/auth/source_test.go index 6a8e28691..67e96ee19 100644 --- a/models/auth/source_test.go +++ b/models/auth/source_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package auth_test import ( "strings" "testing" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/json" @@ -37,13 +38,13 @@ func (source *TestSource) ToDB() ([]byte, error) { func TestDumpAuthSource(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - authSourceSchema, err := db.TableInfo(new(Source)) + authSourceSchema, err := db.TableInfo(new(auth_model.Source)) assert.NoError(t, err) - RegisterTypeConfig(OAuth2, new(TestSource)) + auth_model.RegisterTypeConfig(auth_model.OAuth2, new(TestSource)) - CreateSource(&Source{ - Type: OAuth2, + auth_model.CreateSource(&auth_model.Source{ + Type: auth_model.OAuth2, Name: "TestSource", IsActive: false, Cfg: &TestSource{ diff --git a/models/token.go b/models/auth/token.go similarity index 86% rename from models/token.go rename to models/auth/token.go index b89514309..01654f290 100644 --- a/models/token.go +++ b/models/auth/token.go @@ -3,14 +3,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package auth import ( "crypto/subtle" "fmt" "time" - "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/setting" @@ -21,6 +20,34 @@ import ( lru "github.com/hashicorp/golang-lru" ) +// ErrAccessTokenNotExist represents a "AccessTokenNotExist" kind of error. +type ErrAccessTokenNotExist struct { + Token string +} + +// IsErrAccessTokenNotExist checks if an error is a ErrAccessTokenNotExist. +func IsErrAccessTokenNotExist(err error) bool { + _, ok := err.(ErrAccessTokenNotExist) + return ok +} + +func (err ErrAccessTokenNotExist) Error() string { + return fmt.Sprintf("access token does not exist [sha: %s]", err.Token) +} + +// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error. +type ErrAccessTokenEmpty struct{} + +// IsErrAccessTokenEmpty checks if an error is a ErrAccessTokenEmpty. +func IsErrAccessTokenEmpty(err error) bool { + _, ok := err.(ErrAccessTokenEmpty) + return ok +} + +func (err ErrAccessTokenEmpty) Error() string { + return "access token is empty" +} + var successfulAccessTokenCache *lru.Cache // AccessToken represents a personal access token. @@ -68,7 +95,7 @@ func NewAccessToken(t *AccessToken) error { } t.TokenSalt = salt t.Token = base.EncodeSha1(gouuid.New().String()) - t.TokenHash = auth.HashToken(t.Token, t.TokenSalt) + t.TokenHash = HashToken(t.Token, t.TokenSalt) t.TokenLastEight = t.Token[len(t.Token)-8:] _, err = db.GetEngine(db.DefaultContext).Insert(t) return err @@ -130,7 +157,7 @@ func GetAccessTokenBySHA(token string) (*AccessToken, error) { } for _, t := range tokens { - tempHash := auth.HashToken(token, t.TokenSalt) + tempHash := HashToken(token, t.TokenSalt) if subtle.ConstantTimeCompare([]byte(t.TokenHash), []byte(tempHash)) == 1 { if successfulAccessTokenCache != nil { successfulAccessTokenCache.Add(token, t.ID) diff --git a/models/token_test.go b/models/auth/token_test.go similarity index 62% rename from models/token_test.go rename to models/auth/token_test.go index 007148870..b27ff1340 100644 --- a/models/token_test.go +++ b/models/auth/token_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package auth_test import ( "testing" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -14,77 +15,77 @@ import ( func TestNewAccessToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token := &AccessToken{ + token := &auth_model.AccessToken{ UID: 3, Name: "Token C", } - assert.NoError(t, NewAccessToken(token)) + assert.NoError(t, auth_model.NewAccessToken(token)) unittest.AssertExistsAndLoadBean(t, token) - invalidToken := &AccessToken{ + invalidToken := &auth_model.AccessToken{ ID: token.ID, // duplicate UID: 2, Name: "Token F", } - assert.Error(t, NewAccessToken(invalidToken)) + assert.Error(t, auth_model.NewAccessToken(invalidToken)) } func TestAccessTokenByNameExists(t *testing.T) { name := "Token Gitea" assert.NoError(t, unittest.PrepareTestDatabase()) - token := &AccessToken{ + token := &auth_model.AccessToken{ UID: 3, Name: name, } // Check to make sure it doesn't exists already - exist, err := AccessTokenByNameExists(token) + exist, err := auth_model.AccessTokenByNameExists(token) assert.NoError(t, err) assert.False(t, exist) // Save it to the database - assert.NoError(t, NewAccessToken(token)) + assert.NoError(t, auth_model.NewAccessToken(token)) unittest.AssertExistsAndLoadBean(t, token) // This token must be found by name in the DB now - exist, err = AccessTokenByNameExists(token) + exist, err = auth_model.AccessTokenByNameExists(token) assert.NoError(t, err) assert.True(t, exist) - user4Token := &AccessToken{ + user4Token := &auth_model.AccessToken{ UID: 4, Name: name, } // Name matches but different user ID, this shouldn't exists in the // database - exist, err = AccessTokenByNameExists(user4Token) + exist, err = auth_model.AccessTokenByNameExists(user4Token) assert.NoError(t, err) assert.False(t, exist) } func TestGetAccessTokenBySHA(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := GetAccessTokenBySHA("d2c6c1ba3890b309189a8e618c72a162e4efbf36") + token, err := auth_model.GetAccessTokenBySHA("d2c6c1ba3890b309189a8e618c72a162e4efbf36") assert.NoError(t, err) assert.Equal(t, int64(1), token.UID) assert.Equal(t, "Token A", token.Name) assert.Equal(t, "2b3668e11cb82d3af8c6e4524fc7841297668f5008d1626f0ad3417e9fa39af84c268248b78c481daa7e5dc437784003494f", token.TokenHash) assert.Equal(t, "e4efbf36", token.TokenLastEight) - _, err = GetAccessTokenBySHA("notahash") + _, err = auth_model.GetAccessTokenBySHA("notahash") assert.Error(t, err) - assert.True(t, IsErrAccessTokenNotExist(err)) + assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) - _, err = GetAccessTokenBySHA("") + _, err = auth_model.GetAccessTokenBySHA("") assert.Error(t, err) - assert.True(t, IsErrAccessTokenEmpty(err)) + assert.True(t, auth_model.IsErrAccessTokenEmpty(err)) } func TestListAccessTokens(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - tokens, err := ListAccessTokens(ListAccessTokensOptions{UserID: 1}) + tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 1}) assert.NoError(t, err) if assert.Len(t, tokens, 2) { assert.Equal(t, int64(1), tokens[0].UID) @@ -93,39 +94,39 @@ func TestListAccessTokens(t *testing.T) { assert.Contains(t, []string{tokens[0].Name, tokens[1].Name}, "Token B") } - tokens, err = ListAccessTokens(ListAccessTokensOptions{UserID: 2}) + tokens, err = auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 2}) assert.NoError(t, err) if assert.Len(t, tokens, 1) { assert.Equal(t, int64(2), tokens[0].UID) assert.Equal(t, "Token A", tokens[0].Name) } - tokens, err = ListAccessTokens(ListAccessTokensOptions{UserID: 100}) + tokens, err = auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 100}) assert.NoError(t, err) assert.Empty(t, tokens) } func TestUpdateAccessToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") + token, err := auth_model.GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") assert.NoError(t, err) token.Name = "Token Z" - assert.NoError(t, UpdateAccessToken(token)) + assert.NoError(t, auth_model.UpdateAccessToken(token)) unittest.AssertExistsAndLoadBean(t, token) } func TestDeleteAccessTokenByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") + token, err := auth_model.GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") assert.NoError(t, err) assert.Equal(t, int64(1), token.UID) - assert.NoError(t, DeleteAccessTokenByID(token.ID, 1)) + assert.NoError(t, auth_model.DeleteAccessTokenByID(token.ID, 1)) unittest.AssertNotExistsBean(t, token) - err = DeleteAccessTokenByID(100, 100) + err = auth_model.DeleteAccessTokenByID(100, 100) assert.Error(t, err) - assert.True(t, IsErrAccessTokenNotExist(err)) + assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) } diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go index edbb7ecd5..29344376c 100644 --- a/models/auth/webauthn_test.go +++ b/models/auth/webauthn_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package auth +package auth_test import ( "testing" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/unittest" "github.com/duo-labs/webauthn/webauthn" @@ -16,51 +17,51 @@ import ( func TestGetWebAuthnCredentialByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := GetWebAuthnCredentialByID(1) + res, err := auth_model.GetWebAuthnCredentialByID(1) assert.NoError(t, err) assert.Equal(t, "WebAuthn credential", res.Name) - _, err = GetWebAuthnCredentialByID(342432) + _, err = auth_model.GetWebAuthnCredentialByID(342432) assert.Error(t, err) - assert.True(t, IsErrWebAuthnCredentialNotExist(err)) + assert.True(t, auth_model.IsErrWebAuthnCredentialNotExist(err)) } func TestGetWebAuthnCredentialsByUID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := GetWebAuthnCredentialsByUID(32) + res, err := auth_model.GetWebAuthnCredentialsByUID(32) assert.NoError(t, err) assert.Len(t, res, 1) assert.Equal(t, "WebAuthn credential", res[0].Name) } func TestWebAuthnCredential_TableName(t *testing.T) { - assert.Equal(t, "webauthn_credential", WebAuthnCredential{}.TableName()) + assert.Equal(t, "webauthn_credential", auth_model.WebAuthnCredential{}.TableName()) } func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) + cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) cred.SignCount = 1 assert.NoError(t, cred.UpdateSignCount()) - unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 1}) + unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1}) } func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) + cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) cred.SignCount = 0xffffffff assert.NoError(t, cred.UpdateSignCount()) - unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) + unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) } func TestCreateCredential(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) + res, err := auth_model.CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) assert.NoError(t, err) assert.Equal(t, "WebAuthn Created Credential", res.Name) assert.Equal(t, []byte("Test"), res.CredentialID) - unittest.AssertExistsIf(t, true, &WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1}) + unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1}) } diff --git a/models/consistency.go b/models/consistency.go deleted file mode 100644 index 18ed9195f..000000000 --- a/models/consistency.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/setting" - - "xorm.io/builder" -) - -// CountNullArchivedRepository counts the number of repositories with is_archived is null -func CountNullArchivedRepository() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(repo_model.Repository)) -} - -// FixNullArchivedRepository sets is_archived to false where it is null -func FixNullArchivedRepository() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&repo_model.Repository{ - IsArchived: false, - }) -} - -// CountWrongUserType count OrgUser who have wrong type -func CountWrongUserType() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(user_model.User)) -} - -// FixWrongUserType fix OrgUser who have wrong type -func FixWrongUserType() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&user_model.User{Type: 1}) -} - -// CountActionCreatedUnixString count actions where created_unix is an empty string -func CountActionCreatedUnixString() (int64, error) { - if setting.Database.UseSQLite3 { - return db.GetEngine(db.DefaultContext).Where(`created_unix = ""`).Count(new(Action)) - } - return 0, nil -} - -// FixActionCreatedUnixString set created_unix to zero if it is an empty string -func FixActionCreatedUnixString() (int64, error) { - if setting.Database.UseSQLite3 { - res, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`) - if err != nil { - return 0, err - } - return res.RowsAffected() - } - return 0, nil -} diff --git a/models/db/engine_test.go b/models/db/engine_test.go index 41279c500..c26d94c34 100644 --- a/models/db/engine_test.go +++ b/models/db/engine_test.go @@ -5,7 +5,6 @@ package db_test import ( - "os" "path/filepath" "testing" @@ -20,8 +19,7 @@ import ( func TestDumpDatabase(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - dir, err := os.MkdirTemp(os.TempDir(), "dump") - assert.NoError(t, err) + dir := t.TempDir() type Version struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/error.go b/models/error.go index 3c617904f..873ed0cea 100644 --- a/models/error.go +++ b/models/error.go @@ -57,93 +57,6 @@ func (err ErrUserOwnPackages) Error() string { return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID) } -// __ __.__ __ .__ -// / \ / \__| | _|__| -// \ \/\/ / | |/ / | -// \ /| | <| | -// \__/\ / |__|__|_ \__| -// \/ \/ - -// ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error. -type ErrWikiAlreadyExist struct { - Title string -} - -// IsErrWikiAlreadyExist checks if an error is an ErrWikiAlreadyExist. -func IsErrWikiAlreadyExist(err error) bool { - _, ok := err.(ErrWikiAlreadyExist) - return ok -} - -func (err ErrWikiAlreadyExist) Error() string { - return fmt.Sprintf("wiki page already exists [title: %s]", err.Title) -} - -// ErrWikiReservedName represents a reserved name error. -type ErrWikiReservedName struct { - Title string -} - -// IsErrWikiReservedName checks if an error is an ErrWikiReservedName. -func IsErrWikiReservedName(err error) bool { - _, ok := err.(ErrWikiReservedName) - return ok -} - -func (err ErrWikiReservedName) Error() string { - return fmt.Sprintf("wiki title is reserved: %s", err.Title) -} - -// ErrWikiInvalidFileName represents an invalid wiki file name. -type ErrWikiInvalidFileName struct { - FileName string -} - -// IsErrWikiInvalidFileName checks if an error is an ErrWikiInvalidFileName. -func IsErrWikiInvalidFileName(err error) bool { - _, ok := err.(ErrWikiInvalidFileName) - return ok -} - -func (err ErrWikiInvalidFileName) Error() string { - return fmt.Sprintf("Invalid wiki filename: %s", err.FileName) -} - -// _____ ___________ __ -// / _ \ ____ ____ ____ ______ _____\__ ___/___ | | __ ____ ____ -// / /_\ \_/ ___\/ ___\/ __ \ / ___// ___/ | | / _ \| |/ // __ \ / \ -// / | \ \__\ \__\ ___/ \___ \ \___ \ | |( <_> ) <\ ___/| | \ -// \____|__ /\___ >___ >___ >____ >____ > |____| \____/|__|_ \\___ >___| / -// \/ \/ \/ \/ \/ \/ \/ \/ \/ - -// ErrAccessTokenNotExist represents a "AccessTokenNotExist" kind of error. -type ErrAccessTokenNotExist struct { - Token string -} - -// IsErrAccessTokenNotExist checks if an error is a ErrAccessTokenNotExist. -func IsErrAccessTokenNotExist(err error) bool { - _, ok := err.(ErrAccessTokenNotExist) - return ok -} - -func (err ErrAccessTokenNotExist) Error() string { - return fmt.Sprintf("access token does not exist [sha: %s]", err.Token) -} - -// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error. -type ErrAccessTokenEmpty struct{} - -// IsErrAccessTokenEmpty checks if an error is a ErrAccessTokenEmpty. -func IsErrAccessTokenEmpty(err error) bool { - _, ok := err.(ErrAccessTokenEmpty) - return ok -} - -func (err ErrAccessTokenEmpty) Error() string { - return "access token is empty" -} - // ErrNoPendingRepoTransfer is an error type for repositories without a pending // transfer request type ErrNoPendingRepoTransfer struct { @@ -178,23 +91,6 @@ func (err ErrRepoTransferInProgress) Error() string { return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) } -// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error. -type ErrForkAlreadyExist struct { - Uname string - RepoName string - ForkName string -} - -// IsErrForkAlreadyExist checks if an error is an ErrForkAlreadyExist. -func IsErrForkAlreadyExist(err error) bool { - _, ok := err.(ErrForkAlreadyExist) - return ok -} - -func (err ErrForkAlreadyExist) Error() string { - return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName) -} - // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. type ErrInvalidCloneAddr struct { Host string @@ -243,37 +139,6 @@ func (err ErrUpdateTaskNotExist) Error() string { return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID) } -// ErrReleaseAlreadyExist represents a "ReleaseAlreadyExist" kind of error. -type ErrReleaseAlreadyExist struct { - TagName string -} - -// IsErrReleaseAlreadyExist checks if an error is a ErrReleaseAlreadyExist. -func IsErrReleaseAlreadyExist(err error) bool { - _, ok := err.(ErrReleaseAlreadyExist) - return ok -} - -func (err ErrReleaseAlreadyExist) Error() string { - return fmt.Sprintf("release tag already exist [tag_name: %s]", err.TagName) -} - -// ErrReleaseNotExist represents a "ReleaseNotExist" kind of error. -type ErrReleaseNotExist struct { - ID int64 - TagName string -} - -// IsErrReleaseNotExist checks if an error is a ErrReleaseNotExist. -func IsErrReleaseNotExist(err error) bool { - _, ok := err.(ErrReleaseNotExist) - return ok -} - -func (err ErrReleaseNotExist) Error() string { - return fmt.Sprintf("release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName) -} - // ErrInvalidTagName represents a "InvalidTagName" kind of error. type ErrInvalidTagName struct { TagName string @@ -657,71 +522,3 @@ func (err ErrPullRequestHasMerged) Error() string { return fmt.Sprintf("pull request has merged [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) } - -// _________ __ __ .__ -// / _____// |_ ____ ________ _ _______ _/ |_ ____ | |__ -// \_____ \\ __\/ _ \\____ \ \/ \/ /\__ \\ __\/ ___\| | \ -// / \| | ( <_> ) |_> > / / __ \| | \ \___| Y \ -// /_______ /|__| \____/| __/ \/\_/ (____ /__| \___ >___| / -// \/ |__| \/ \/ \/ - -// ErrStopwatchNotExist represents a "Stopwatch Not Exist" kind of error. -type ErrStopwatchNotExist struct { - ID int64 -} - -// IsErrStopwatchNotExist checks if an error is a ErrStopwatchNotExist. -func IsErrStopwatchNotExist(err error) bool { - _, ok := err.(ErrStopwatchNotExist) - return ok -} - -func (err ErrStopwatchNotExist) Error() string { - return fmt.Sprintf("stopwatch does not exist [id: %d]", err.ID) -} - -// ___________ __ .______________.__ -// \__ ___/___________ ____ | | __ ____ __| _/\__ ___/|__| _____ ____ -// | | \_ __ \__ \ _/ ___\| |/ // __ \ / __ | | | | |/ \_/ __ \ -// | | | | \// __ \\ \___| <\ ___// /_/ | | | | | Y Y \ ___/ -// |____| |__| (____ /\___ >__|_ \\___ >____ | |____| |__|__|_| /\___ > -// \/ \/ \/ \/ \/ \/ \/ - -// ErrTrackedTimeNotExist represents a "TrackedTime Not Exist" kind of error. -type ErrTrackedTimeNotExist struct { - ID int64 -} - -// IsErrTrackedTimeNotExist checks if an error is a ErrTrackedTimeNotExist. -func IsErrTrackedTimeNotExist(err error) bool { - _, ok := err.(ErrTrackedTimeNotExist) - return ok -} - -func (err ErrTrackedTimeNotExist) Error() string { - return fmt.Sprintf("tracked time does not exist [id: %d]", err.ID) -} - -// ____ ___ .__ .___ -// | | \______ | | _________ __| _/ -// | | /\____ \| | / _ \__ \ / __ | -// | | / | |_> > |_( <_> ) __ \_/ /_/ | -// |______/ | __/|____/\____(____ /\____ | -// |__| \/ \/ -// - -// ErrUploadNotExist represents a "UploadNotExist" kind of error. -type ErrUploadNotExist struct { - ID int64 - UUID string -} - -// IsErrUploadNotExist checks if an error is a ErrUploadNotExist. -func IsErrUploadNotExist(err error) bool { - _, ok := err.(ErrUploadNotExist) - return ok -} - -func (err ErrUploadNotExist) Error() string { - return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) -} diff --git a/models/fixtures/org_user.yml b/models/fixtures/org_user.yml index a0bc4b9b4..e06d94cfc 100644 --- a/models/fixtures/org_user.yml +++ b/models/fixtures/org_user.yml @@ -63,3 +63,9 @@ uid: 29 org_id: 17 is_public: true + +- + id: 12 + uid: 2 + org_id: 17 + is_public: true diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index 67ba869c7..87405bfd2 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -309,7 +309,7 @@ avatar_email: user17@example.com num_repos: 2 is_active: true - num_members: 3 + num_members: 4 num_teams: 3 - diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index aed78611e..8299087c5 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -68,6 +68,7 @@ func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) { issues, err := Issues(&IssuesOptions{ ProjectBoardID: b.ID, ProjectID: b.ProjectID, + SortType: "project-column-sorting", }) if err != nil { return nil, err @@ -79,6 +80,7 @@ func LoadIssuesFromBoard(b *project_model.Board) (IssueList, error) { issues, err := Issues(&IssuesOptions{ ProjectBoardID: -1, // Issues without ProjectBoardID ProjectID: b.ProjectID, + SortType: "project-column-sorting", }) if err != nil { return nil, err diff --git a/models/main_test.go b/models/main_test.go index bb2fedc15..49b6e3e56 100644 --- a/models/main_test.go +++ b/models/main_test.go @@ -7,6 +7,7 @@ package models import ( "testing" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -28,7 +29,7 @@ func TestFixturesAreConsistent(t *testing.T) { &user_model.User{}, &repo_model.Repository{}, &organization.Team{}, - &Action{}) + &activities_model.Action{}) } func TestMain(m *testing.M) { diff --git a/models/migrate.go b/models/migrate.go index 0af3891cb..f6bceaa01 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/structs" ) @@ -154,7 +155,7 @@ func InsertPullRequests(prs ...*issues_model.PullRequest) error { } // InsertReleases migrates release -func InsertReleases(rels ...*Release) error { +func InsertReleases(rels ...*repo_model.Release) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -191,7 +192,7 @@ func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, us return err } - if err := UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { + if err := repo_model.UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { return err } diff --git a/models/migrate_test.go b/models/migrate_test.go index 627fb1ae7..bc7729673 100644 --- a/models/migrate_test.go +++ b/models/migrate_test.go @@ -149,7 +149,7 @@ func TestMigrate_InsertReleases(t *testing.T) { a := &repo_model.Attachment{ UUID: "a0eebc91-9c0c-4ef7-bb6e-6bb9bd380a12", } - r := &Release{ + r := &repo_model.Release{ Attachments: []*repo_model.Attachment{a}, } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 30c4ad250..28ffc9988 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -406,8 +406,13 @@ var migrations = []Migration{ NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn), // v223 -> v224 NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes), + + // Gitea 1.17.0 ends at v224 + // v224 -> v225 - NewMigration("Add badges to users", creatUserBadgesTable), + NewMigration("Add badges to users", createUserBadgesTable), + // v225 -> v226 + NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go index 53e4f3539..5cd70626b 100644 --- a/models/migrations/migrations_test.go +++ b/models/migrations/migrations_test.go @@ -46,7 +46,7 @@ func TestMain(m *testing.M) { giteaConf := os.Getenv("GITEA_CONF") if giteaConf == "" { - giteaConf = path.Join(filepath.Dir(setting.AppPath), "integrations/sqlite.ini") + giteaConf = path.Join(filepath.Dir(setting.AppPath), "tests/sqlite.ini") fmt.Printf("Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf) } @@ -205,7 +205,7 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En ourSkip += skip deferFn := PrintCurrentTest(t, ourSkip) assert.NoError(t, os.RemoveAll(setting.RepoRootPath)) - assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) + assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath)) ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil { assert.NoError(t, err, "unable to read the new repo root: %v\n", err) diff --git a/models/migrations/testlogger_test.go b/models/migrations/testlogger_test.go index adbf19c0d..0455d9c9a 100644 --- a/models/migrations/testlogger_test.go +++ b/models/migrations/testlogger_test.go @@ -188,5 +188,5 @@ func (log *TestLogger) GetName() string { func init() { log.Register("test", NewTestLogger) _, filename, _, _ := runtime.Caller(0) - prefix = strings.TrimSuffix(filename, "integrations/testlogger.go") + prefix = strings.TrimSuffix(filename, "tests/testlogger.go") } diff --git a/models/migrations/v218.go b/models/migrations/v218.go index dee8e5517..e08c6c5b0 100644 --- a/models/migrations/v218.go +++ b/models/migrations/v218.go @@ -5,6 +5,7 @@ package migrations import ( + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "xorm.io/xorm" @@ -37,8 +38,14 @@ func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index { actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType) actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted") + indices := []*schemas.Index{actUserIndex, repoIndex} + if setting.Database.UsePostgreSQL { + cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType) + cudIndex.AddColumn("created_unix", "user_id", "is_deleted") + indices = append(indices, cudIndex) + } - return []*schemas.Index{actUserIndex, repoIndex} + return indices } func improveActionTableIndices(x *xorm.Engine) error { diff --git a/models/migrations/v224.go b/models/migrations/v224.go index d684d538d..2ed161ef4 100644 --- a/models/migrations/v224.go +++ b/models/migrations/v224.go @@ -8,7 +8,7 @@ import ( "xorm.io/xorm" ) -func creatUserBadgesTable(x *xorm.Engine) error { +func createUserBadgesTable(x *xorm.Engine) error { type Badge struct { ID int64 `xorm:"pk autoincr"` Description string diff --git a/models/migrations/v225.go b/models/migrations/v225.go new file mode 100644 index 000000000..6dd460eb6 --- /dev/null +++ b/models/migrations/v225.go @@ -0,0 +1,29 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func alterPublicGPGKeyContentFieldsToMediumText(x *xorm.Engine) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if setting.Database.UseMySQL { + if _, err := sess.Exec("ALTER TABLE `gpg_key` CHANGE `content` `content` MEDIUMTEXT"); err != nil { + return err + } + if _, err := sess.Exec("ALTER TABLE `public_key` CHANGE `content` `content` MEDIUMTEXT"); err != nil { + return err + } + } + return sess.Commit() +} diff --git a/models/org.go b/models/org.go index efcb7183e..53be80c3d 100644 --- a/models/org.go +++ b/models/org.go @@ -8,79 +8,13 @@ package models import ( "context" "fmt" - "strings" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unit" - user_model "code.gitea.io/gitea/models/user" - - "xorm.io/builder" ) -// MinimalOrg represents a simple orgnization with only needed columns -type MinimalOrg = organization.Organization - -// GetUserOrgsList returns one user's all orgs list -func GetUserOrgsList(user *user_model.User) ([]*MinimalOrg, error) { - schema, err := db.TableInfo(new(user_model.User)) - if err != nil { - return nil, err - } - - outputCols := []string{ - "id", - "name", - "full_name", - "visibility", - "avatar", - "avatar_email", - "use_custom_avatar", - } - - groupByCols := &strings.Builder{} - for _, col := range outputCols { - fmt.Fprintf(groupByCols, "`%s`.%s,", schema.Name, col) - } - groupByStr := groupByCols.String() - groupByStr = groupByStr[0 : len(groupByStr)-1] - - sess := db.GetEngine(db.DefaultContext) - sess = sess.Select(groupByStr+", count(distinct repo_id) as org_count"). - Table("user"). - Join("INNER", "team", "`team`.org_id = `user`.id"). - Join("INNER", "team_user", "`team`.id = `team_user`.team_id"). - Join("LEFT", builder. - Select("id as repo_id, owner_id as repo_owner_id"). - From("repository"). - Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), "`repository`.repo_owner_id = `team`.org_id"). - Where("`team_user`.uid = ?", user.ID). - GroupBy(groupByStr) - - type OrgCount struct { - organization.Organization `xorm:"extends"` - OrgCount int - } - - orgCounts := make([]*OrgCount, 0, 10) - - if err := sess. - Asc("`user`.name"). - Find(&orgCounts); err != nil { - return nil, err - } - - orgs := make([]*MinimalOrg, len(orgCounts)) - for i, orgCount := range orgCounts { - orgCount.Organization.NumRepos = orgCount.OrgCount - orgs[i] = &orgCount.Organization - } - - return orgs, nil -} - func removeOrgUser(ctx context.Context, orgID, userID int64) error { ou := new(organization.OrgUser) diff --git a/models/org_team.go b/models/org_team.go index 5d29e3333..61ddd2a04 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -25,12 +25,12 @@ import ( "xorm.io/builder" ) -func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.Repository) (err error) { +func AddRepository(ctx context.Context, t *organization.Team, repo *repo_model.Repository) (err error) { if err = organization.AddTeamRepo(ctx, t.OrgID, t.ID, repo.ID); err != nil { return err } - if _, err = db.GetEngine(ctx).Incr("num_repos").ID(t.ID).Update(new(organization.Team)); err != nil { + if err = organization.IncrTeamRepoNum(ctx, t.ID); err != nil { return fmt.Errorf("update team: %v", err) } @@ -58,16 +58,15 @@ func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.R // addAllRepositories adds all repositories to the team. // If the team already has some repositories they will be left unchanged. func addAllRepositories(ctx context.Context, t *organization.Team) error { - var orgRepos []repo_model.Repository - e := db.GetEngine(ctx) - if err := e.Where("owner_id = ?", t.OrgID).Find(&orgRepos); err != nil { + orgRepos, err := organization.GetOrgRepositories(ctx, t.OrgID) + if err != nil { return fmt.Errorf("get org repos: %v", err) } for _, repo := range orgRepos { if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) { - if err := addRepository(ctx, t, &repo); err != nil { - return fmt.Errorf("addRepository: %v", err) + if err := AddRepository(ctx, t, repo); err != nil { + return fmt.Errorf("AddRepository: %v", err) } } } @@ -90,27 +89,6 @@ func AddAllRepositories(t *organization.Team) (err error) { return committer.Commit() } -// AddRepository adds new repository to team of organization. -func AddRepository(t *organization.Team, repo *repo_model.Repository) (err error) { - if repo.OwnerID != t.OrgID { - return errors.New("Repository does not belong to organization") - } else if HasRepository(t, repo.ID) { - return nil - } - - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err = addRepository(ctx, t, repo); err != nil { - return err - } - - return committer.Commit() -} - // RemoveAllRepositories removes all repositories from team and recalculates access func RemoveAllRepositories(t *organization.Team) (err error) { if t.IncludesAllRepositories { diff --git a/models/org_team_test.go b/models/org_team_test.go index a0de6d73f..a600d07c0 100644 --- a/models/org_team_test.go +++ b/models/org_team_test.go @@ -68,25 +68,6 @@ func TestTeam_HasRepository(t *testing.T) { test(2, 5, false) } -func TestTeam_AddRepository(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - testSuccess := func(teamID, repoID int64) { - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - assert.NoError(t, AddRepository(team, repo)) - unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) - unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) - } - testSuccess(2, 3) - testSuccess(2, 5) - - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.Error(t, AddRepository(team, repo)) - unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1}) -} - func TestTeam_RemoveRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) diff --git a/models/organization/mini_org.go b/models/organization/mini_org.go new file mode 100644 index 000000000..36cf948e6 --- /dev/null +++ b/models/organization/mini_org.go @@ -0,0 +1,78 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package organization + +import ( + "fmt" + "strings" + + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" + user_model "code.gitea.io/gitea/models/user" + + "xorm.io/builder" +) + +// MinimalOrg represents a simple organization with only the needed columns +type MinimalOrg = Organization + +// GetUserOrgsList returns all organizations the given user has access to +func GetUserOrgsList(user *user_model.User) ([]*MinimalOrg, error) { + schema, err := db.TableInfo(new(user_model.User)) + if err != nil { + return nil, err + } + + outputCols := []string{ + "id", + "name", + "full_name", + "visibility", + "avatar", + "avatar_email", + "use_custom_avatar", + } + + groupByCols := &strings.Builder{} + for _, col := range outputCols { + fmt.Fprintf(groupByCols, "`%s`.%s,", schema.Name, col) + } + groupByStr := groupByCols.String() + groupByStr = groupByStr[0 : len(groupByStr)-1] + + sess := db.GetEngine(db.DefaultContext) + sess = sess.Select(groupByStr+", count(distinct repo_id) as org_count"). + Table("user"). + Join("INNER", "team", "`team`.org_id = `user`.id"). + Join("INNER", "team_user", "`team`.id = `team_user`.team_id"). + Join("LEFT", builder. + Select("id as repo_id, owner_id as repo_owner_id"). + From("repository"). + Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), "`repository`.repo_owner_id = `team`.org_id"). + Where("`team_user`.uid = ?", user.ID). + GroupBy(groupByStr) + + type OrgCount struct { + Organization `xorm:"extends"` + OrgCount int + } + + orgCounts := make([]*OrgCount, 0, 10) + + if err := sess. + Asc("`user`.name"). + Find(&orgCounts); err != nil { + return nil, err + } + + orgs := make([]*MinimalOrg, len(orgCounts)) + for i, orgCount := range orgCounts { + orgCount.Organization.NumRepos = orgCount.OrgCount + orgs[i] = &orgCount.Organization + } + + return orgs, nil +} diff --git a/models/organization/org_repo.go b/models/organization/org_repo.go new file mode 100644 index 000000000..364374f71 --- /dev/null +++ b/models/organization/org_repo.go @@ -0,0 +1,18 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package organization + +import ( + "context" + + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" +) + +// GetOrgRepositories get repos belonging to the given organization +func GetOrgRepositories(ctx context.Context, orgID int64) ([]*repo_model.Repository, error) { + var orgRepos []*repo_model.Repository + return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) +} diff --git a/models/organization/team.go b/models/organization/team.go index 0b53c84d6..2d5ee1727 100644 --- a/models/organization/team.go +++ b/models/organization/team.go @@ -96,16 +96,7 @@ type SearchTeamOptions struct { IncludeDesc bool } -// SearchTeam search for teams. Caller is responsible to check permissions. -func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { - if opts.Page <= 0 { - opts.Page = 1 - } - if opts.PageSize == 0 { - // Default limit - opts.PageSize = 10 - } - +func (opts *SearchTeamOptions) toCond() builder.Cond { cond := builder.NewCond() if len(opts.Keyword) > 0 { @@ -117,10 +108,28 @@ func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { cond = cond.And(keywordCond) } - cond = cond.And(builder.Eq{"org_id": opts.OrgID}) + if opts.OrgID > 0 { + cond = cond.And(builder.Eq{"`team`.org_id": opts.OrgID}) + } + if opts.UserID > 0 { + cond = cond.And(builder.Eq{"team_user.uid": opts.UserID}) + } + + return cond +} + +// SearchTeam search for teams. Caller is responsible to check permissions. +func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { sess := db.GetEngine(db.DefaultContext) + opts.SetDefaultValues() + cond := opts.toCond() + + if opts.UserID > 0 { + sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id") + } + count, err := sess. Where(cond). Count(new(Team)) @@ -128,7 +137,10 @@ func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { return nil, 0, err } - sess = sess.Where(cond) + if opts.UserID > 0 { + sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id") + } + if opts.PageSize == -1 { opts.PageSize = int(count) } else { @@ -137,6 +149,7 @@ func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) { teams := make([]*Team, 0, opts.PageSize) if err = sess. + Where(cond). OrderBy("lower_name"). Find(&teams); err != nil { return nil, 0, err @@ -346,3 +359,9 @@ func GetRepoTeams(ctx context.Context, repo *repo_model.Repository) (teams []*Te OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END"). Find(&teams) } + +// IncrTeamRepoNum increases the number of repos for the given team by 1 +func IncrTeamRepoNum(ctx context.Context, teamID int64) error { + _, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team)) + return err +} diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index dc753421d..357574a70 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/packages/pub" "code.gitea.io/gitea/modules/packages/pypi" "code.gitea.io/gitea/modules/packages/rubygems" + "code.gitea.io/gitea/modules/packages/vagrant" "github.com/hashicorp/go-version" ) @@ -150,6 +151,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc metadata = &pypi.Metadata{} case TypeRubyGems: metadata = &rubygems.Metadata{} + case TypeVagrant: + metadata = &vagrant.Metadata{} default: panic(fmt.Sprintf("unknown package type: %s", string(p.Type))) } diff --git a/models/packages/package.go b/models/packages/package.go index 39b1c83cf..e39a7c4e4 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -42,6 +42,7 @@ const ( TypePub Type = "pub" TypePyPI Type = "pypi" TypeRubyGems Type = "rubygems" + TypeVagrant Type = "vagrant" ) // Name gets the name of the package type @@ -69,6 +70,8 @@ func (pt Type) Name() string { return "PyPI" case TypeRubyGems: return "RubyGems" + case TypeVagrant: + return "Vagrant" } panic(fmt.Sprintf("unknown package type: %s", string(pt))) } @@ -98,6 +101,8 @@ func (pt Type) SVGName() string { return "gitea-python" case TypeRubyGems: return "gitea-rubygems" + case TypeVagrant: + return "gitea-vagrant" } panic(fmt.Sprintf("unknown package type: %s", string(pt))) } @@ -219,9 +224,16 @@ func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) { Find(&ps) } -// HasOwnerPackages tests if a user/org has packages +// HasOwnerPackages tests if a user/org has accessible packages func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) { - return db.GetEngine(ctx).Where("owner_id = ?", ownerID).Exist(&Package{}) + return db.GetEngine(ctx). + Table("package_version"). + Join("INNER", "package", "package.id = package_version.package_id"). + Where(builder.Eq{ + "package_version.is_internal": false, + "package.owner_id": ownerID, + }). + Exist(&PackageVersion{}) } // HasRepositoryPackages tests if a repository has packages diff --git a/models/packages/package_test.go b/models/packages/package_test.go new file mode 100644 index 000000000..3d3a2333b --- /dev/null +++ b/models/packages/package_test.go @@ -0,0 +1,69 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package packages_test + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models/db" + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + + _ "code.gitea.io/gitea/models" + + "github.com/stretchr/testify/assert" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: filepath.Join("..", ".."), + }) +} + +func TestHasOwnerPackages(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + + p, err := packages_model.TryInsertPackage(db.DefaultContext, &packages_model.Package{ + OwnerID: owner.ID, + LowerName: "package", + }) + assert.NotNil(t, p) + assert.NoError(t, err) + + // A package without package versions gets automatically cleaned up and should return false + has, err := packages_model.HasOwnerPackages(db.DefaultContext, owner.ID) + assert.False(t, has) + assert.NoError(t, err) + + pv, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{ + PackageID: p.ID, + LowerVersion: "internal", + IsInternal: true, + }) + assert.NotNil(t, pv) + assert.NoError(t, err) + + // A package with an internal package version gets automaticaly cleaned up and should return false + has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID) + assert.False(t, has) + assert.NoError(t, err) + + pv, err = packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{ + PackageID: p.ID, + LowerVersion: "normal", + IsInternal: false, + }) + assert.NotNil(t, pv) + assert.NoError(t, err) + + // A package with a normal package version should return true + has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID) + assert.True(t, has) + assert.NoError(t, err) +} diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go index 8e75792e0..7f58be4f3 100644 --- a/models/perm/access/access_test.go +++ b/models/perm/access/access_test.go @@ -7,13 +7,10 @@ package access_test import ( "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/organization" perm_model "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -128,249 +125,3 @@ func TestRepository_RecalculateAccesses2(t *testing.T) { assert.NoError(t, err) assert.False(t, has) } - -func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - // public non-organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) - assert.NoError(t, repo.LoadUnits(db.DefaultContext)) - - // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // change to collaborator - assert.NoError(t, models.AddCollaborator(repo, user)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // collaborator - collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } -} - -func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - // private non-organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.NoError(t, repo.LoadUnits(db.DefaultContext)) - - // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) - perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.False(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // change to collaborator to default write access - assert.NoError(t, models.AddCollaborator(repo, user)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } -} - -func TestRepoPermissionPublicOrgRepo(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - // public organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) - assert.NoError(t, repo.LoadUnits(db.DefaultContext)) - - // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) - perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // change to collaborator to default write access - assert.NoError(t, models.AddCollaborator(repo, user)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // org member team owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // org member team tester - member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - } - assert.True(t, perm.CanWrite(unit.TypeIssues)) - assert.False(t, perm.CanWrite(unit.TypeCode)) - - // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } -} - -func TestRepoPermissionPrivateOrgRepo(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - // private organization repo - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) - assert.NoError(t, repo.LoadUnits(db.DefaultContext)) - - // plain user - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) - perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.False(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // change to collaborator to default write access - assert.NoError(t, models.AddCollaborator(repo, user)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.False(t, perm.CanWrite(unit.Type)) - } - - // org member team owner - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // update team information and then check permission - team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) - err = organization.UpdateTeamUnits(team, nil) - assert.NoError(t, err) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } - - // org member team tester - tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) - assert.NoError(t, err) - assert.True(t, perm.CanWrite(unit.TypeIssues)) - assert.False(t, perm.CanWrite(unit.TypeCode)) - assert.False(t, perm.CanRead(unit.TypeCode)) - - // org member team reviewer - reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) - assert.NoError(t, err) - assert.False(t, perm.CanRead(unit.TypeIssues)) - assert.False(t, perm.CanWrite(unit.TypeCode)) - assert.True(t, perm.CanRead(unit.TypeCode)) - - // admin - admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) - assert.NoError(t, err) - for _, unit := range repo.Units { - assert.True(t, perm.CanRead(unit.Type)) - assert.True(t, perm.CanWrite(unit.Type)) - } -} diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go index 99919c70b..93e3bdd6d 100644 --- a/models/perm/access/repo_permission.go +++ b/models/perm/access/repo_permission.go @@ -430,3 +430,17 @@ func IsRepoReader(ctx context.Context, repo *repo_model.Repository, userID int64 } return db.GetEngine(ctx).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm_model.AccessModeRead).Get(&Access{}) } + +// CheckRepoUnitUser check whether user could visit the unit of this repository +func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool { + if user != nil && user.IsAdmin { + return true + } + perm, err := GetUserRepoPermission(ctx, repo, user) + if err != nil { + log.Error("GetUserRepoPermission: %w", err) + return false + } + + return perm.CanRead(unitType) +} diff --git a/models/repo.go b/models/repo.go index 66ef51473..f2676a569 100644 --- a/models/repo.go +++ b/models/repo.go @@ -12,13 +12,13 @@ import ( _ "image/jpeg" // Needed for jpeg support + activities_model "code.gitea.io/gitea/models/activities" admin_model "code.gitea.io/gitea/models/admin" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" - "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" @@ -27,10 +27,7 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" - api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -40,162 +37,6 @@ func NewRepoContext() { unit.LoadUnitConfig() } -// CheckRepoUnitUser check whether user could visit the unit of this repository -func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool { - if user != nil && user.IsAdmin { - return true - } - perm, err := access_model.GetUserRepoPermission(ctx, repo, user) - if err != nil { - log.Error("GetUserRepoPermission(): %v", err) - return false - } - - return perm.CanRead(unitType) -} - -// CreateRepoOptions contains the create repository options -type CreateRepoOptions struct { - Name string - Description string - OriginalURL string - GitServiceType api.GitServiceType - Gitignores string - IssueLabels string - License string - Readme string - DefaultBranch string - IsPrivate bool - IsMirror bool - IsTemplate bool - AutoInit bool - Status repo_model.RepositoryStatus - TrustModel repo_model.TrustModelType - MirrorInterval string -} - -// CreateRepository creates a repository for the user/organization. -func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { - if err = repo_model.IsUsableRepoName(repo.Name); err != nil { - return err - } - - has, err := repo_model.IsRepositoryExist(ctx, u, repo.Name) - if err != nil { - return fmt.Errorf("IsRepositoryExist: %v", err) - } else if has { - return repo_model.ErrRepoAlreadyExist{ - Uname: u.Name, - Name: repo.Name, - } - } - - repoPath := repo_model.RepoPath(u.Name, repo.Name) - isExist, err := util.IsExist(repoPath) - if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) - return err - } - if !overwriteOrAdopt && isExist { - log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) - return repo_model.ErrRepoFilesAlreadyExist{ - Uname: u.Name, - Name: repo.Name, - } - } - - if err = db.Insert(ctx, repo); err != nil { - return err - } - if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil { - return err - } - - // insert units for repo - units := make([]repo_model.RepoUnit, 0, len(unit.DefaultRepoUnits)) - for _, tp := range unit.DefaultRepoUnits { - if tp == unit.TypeIssues { - units = append(units, repo_model.RepoUnit{ - RepoID: repo.ID, - Type: tp, - Config: &repo_model.IssuesConfig{ - EnableTimetracker: setting.Service.DefaultEnableTimetracking, - AllowOnlyContributorsToTrackTime: setting.Service.DefaultAllowOnlyContributorsToTrackTime, - EnableDependencies: setting.Service.DefaultEnableDependencies, - }, - }) - } else if tp == unit.TypePullRequests { - units = append(units, repo_model.RepoUnit{ - RepoID: repo.ID, - Type: tp, - Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle), AllowRebaseUpdate: true}, - }) - } else { - units = append(units, repo_model.RepoUnit{ - RepoID: repo.ID, - Type: tp, - }) - } - } - - if err = db.Insert(ctx, units); err != nil { - return err - } - - // Remember visibility preference. - u.LastRepoVisibility = repo.IsPrivate - if err = user_model.UpdateUserCols(ctx, u, "last_repo_visibility"); err != nil { - return fmt.Errorf("updateUser: %v", err) - } - - if _, err = db.GetEngine(ctx).Incr("num_repos").ID(u.ID).Update(new(user_model.User)); err != nil { - return fmt.Errorf("increment user total_repos: %v", err) - } - u.NumRepos++ - - // Give access to all members in teams with access to all repositories. - if u.IsOrganization() { - teams, err := organization.FindOrgTeams(ctx, u.ID) - if err != nil { - return fmt.Errorf("loadTeams: %v", err) - } - for _, t := range teams { - if t.IncludesAllRepositories { - if err := addRepository(ctx, t, repo); err != nil { - return fmt.Errorf("addRepository: %v", err) - } - } - } - - if isAdmin, err := access_model.IsUserRepoAdmin(ctx, repo, doer); err != nil { - return fmt.Errorf("IsUserRepoAdminCtx: %v", err) - } else if !isAdmin { - // Make creator repo admin if it wasn't assigned automatically - if err = addCollaborator(ctx, repo, doer); err != nil { - return fmt.Errorf("AddCollaborator: %v", err) - } - if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil { - return fmt.Errorf("ChangeCollaborationAccessMode: %v", err) - } - } - } else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { - // Organization automatically called this in addRepository method. - return fmt.Errorf("recalculateAccesses: %v", err) - } - - if setting.Service.AutoWatchNewRepos { - if err = repo_model.WatchRepo(ctx, doer.ID, repo.ID, true); err != nil { - return fmt.Errorf("watchRepo: %v", err) - } - } - - if err = webhook.CopyDefaultWebhooksToRepo(ctx, repo.ID); err != nil { - return fmt.Errorf("copyDefaultWebhooksToRepo: %v", err) - } - - return nil -} - // DeleteRepository deletes a repository for a user or organization. // make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock) func DeleteRepository(doer *user_model.User, uid, repoID int64) error { @@ -279,7 +120,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { if err := db.DeleteBeans(ctx, &access_model.Access{RepoID: repo.ID}, - &Action{RepoID: repo.ID}, + &activities_model.Action{RepoID: repo.ID}, &repo_model.Collaboration{RepoID: repoID}, &issues_model.Comment{RefRepoID: repoID}, &git_model.CommitStatus{RepoID: repoID}, @@ -289,16 +130,16 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { &repo_model.LanguageStat{RepoID: repoID}, &issues_model.Milestone{RepoID: repoID}, &repo_model.Mirror{RepoID: repoID}, - &Notification{RepoID: repoID}, + &activities_model.Notification{RepoID: repoID}, &git_model.ProtectedBranch{RepoID: repoID}, &git_model.ProtectedTag{RepoID: repoID}, &repo_model.PushMirror{RepoID: repoID}, - &Release{RepoID: repoID}, + &repo_model.Release{RepoID: repoID}, &repo_model.RepoIndexerStatus{RepoID: repoID}, &repo_model.Redirect{RedirectRepoID: repoID}, &repo_model.RepoUnit{RepoID: repoID}, &repo_model.Star{RepoID: repoID}, - &Task{RepoID: repoID}, + &admin_model.Task{RepoID: repoID}, &repo_model.Watch{RepoID: repoID}, &webhook.Webhook{RepoID: repoID}, ); err != nil { @@ -377,8 +218,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { archivePaths := make([]string, 0, len(archives)) for _, v := range archives { - p, _ := v.RelativePath() - archivePaths = append(archivePaths, p) + archivePaths = append(archivePaths, v.RelativePath()) } if _, err := db.DeleteByBean(ctx, &repo_model.RepoArchiver{RepoID: repoID}); err != nil { diff --git a/models/repo/archiver.go b/models/repo/archiver.go index fd07d8554..003911943 100644 --- a/models/repo/archiver.go +++ b/models/repo/archiver.go @@ -39,9 +39,9 @@ func init() { db.RegisterModel(new(RepoArchiver)) } -// RelativePath returns relative path -func (archiver *RepoArchiver) RelativePath() (string, error) { - return fmt.Sprintf("%d/%s/%s.%s", archiver.RepoID, archiver.CommitID[:2], archiver.CommitID, archiver.Type.String()), nil +// RelativePath returns the archive path relative to the archive storage root. +func (archiver *RepoArchiver) RelativePath() string { + return fmt.Sprintf("%d/%s/%s.%s", archiver.RepoID, archiver.CommitID[:2], archiver.CommitID, archiver.Type.String()) } var delRepoArchiver = new(RepoArchiver) diff --git a/models/release.go b/models/repo/release.go similarity index 85% rename from models/release.go rename to models/repo/release.go index b169920f2..9a4de26c6 100644 --- a/models/release.go +++ b/models/repo/release.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package repo import ( "context" @@ -14,7 +14,6 @@ import ( "strings" "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" @@ -23,14 +22,45 @@ import ( "xorm.io/builder" ) +// ErrReleaseAlreadyExist represents a "ReleaseAlreadyExist" kind of error. +type ErrReleaseAlreadyExist struct { + TagName string +} + +// IsErrReleaseAlreadyExist checks if an error is a ErrReleaseAlreadyExist. +func IsErrReleaseAlreadyExist(err error) bool { + _, ok := err.(ErrReleaseAlreadyExist) + return ok +} + +func (err ErrReleaseAlreadyExist) Error() string { + return fmt.Sprintf("release tag already exist [tag_name: %s]", err.TagName) +} + +// ErrReleaseNotExist represents a "ReleaseNotExist" kind of error. +type ErrReleaseNotExist struct { + ID int64 + TagName string +} + +// IsErrReleaseNotExist checks if an error is a ErrReleaseNotExist. +func IsErrReleaseNotExist(err error) bool { + _, ok := err.(ErrReleaseNotExist) + return ok +} + +func (err ErrReleaseNotExist) Error() string { + return fmt.Sprintf("release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName) +} + // Release represents a release of repository. type Release struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"INDEX UNIQUE(n)"` - Repo *repo_model.Repository `xorm:"-"` - PublisherID int64 `xorm:"INDEX"` - Publisher *user_model.User `xorm:"-"` - TagName string `xorm:"INDEX UNIQUE(n)"` + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"INDEX UNIQUE(n)"` + Repo *Repository `xorm:"-"` + PublisherID int64 `xorm:"INDEX"` + Publisher *user_model.User `xorm:"-"` + TagName string `xorm:"INDEX UNIQUE(n)"` OriginalAuthor string OriginalAuthorID int64 `xorm:"index"` LowerTagName string @@ -38,14 +68,14 @@ type Release struct { Title string Sha1 string `xorm:"VARCHAR(40)"` NumCommits int64 - NumCommitsBehind int64 `xorm:"-"` - Note string `xorm:"TEXT"` - RenderedNote string `xorm:"-"` - IsDraft bool `xorm:"NOT NULL DEFAULT false"` - IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` - IsTag bool `xorm:"NOT NULL DEFAULT false"` - Attachments []*repo_model.Attachment `xorm:"-"` - CreatedUnix timeutil.TimeStamp `xorm:"INDEX"` + NumCommitsBehind int64 `xorm:"-"` + Note string `xorm:"TEXT"` + RenderedNote string `xorm:"-"` + IsDraft bool `xorm:"NOT NULL DEFAULT false"` + IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` + IsTag bool `xorm:"NOT NULL DEFAULT false"` + Attachments []*Attachment `xorm:"-"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX"` } func init() { @@ -55,7 +85,7 @@ func init() { func (r *Release) loadAttributes(ctx context.Context) error { var err error if r.Repo == nil { - r.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, r.RepoID) + r.Repo, err = GetRepositoryByIDCtx(ctx, r.RepoID) if err != nil { return err } @@ -116,7 +146,7 @@ func UpdateRelease(ctx context.Context, rel *Release) error { // AddReleaseAttachments adds a release attachments func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { // Check attachments - attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, attachmentUUIDs) + attachments, err := GetAttachmentsByUUIDs(ctx, attachmentUUIDs) if err != nil { return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) } @@ -279,9 +309,9 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) { // Sort sortedRels := releaseMetaSearch{ID: make([]int64, len(rels)), Rel: make([]*Release, len(rels))} - var attachments []*repo_model.Attachment + var attachments []*Attachment for index, element := range rels { - element.Attachments = []*repo_model.Attachment{} + element.Attachments = []*Attachment{} sortedRels.ID[index] = element.ID sortedRels.Rel[index] = element } @@ -291,7 +321,7 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) { err = db.GetEngine(ctx). Asc("release_id", "name"). In("release_id", sortedRels.ID). - Find(&attachments, repo_model.Attachment{}) + Find(&attachments, Attachment{}) if err != nil { return err } @@ -354,7 +384,7 @@ func UpdateReleasesMigrationsByType(gitServiceType structs.GitServiceType, origi } // PushUpdateDeleteTagsContext updates a number of delete tags with context -func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repository, tags []string) error { +func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error { if len(tags) == 0 { return nil } @@ -384,7 +414,7 @@ func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repositor } // PushUpdateDeleteTag must be called for any push actions to delete tag -func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { +func PushUpdateDeleteTag(repo *Repository, tagName string) error { rel, err := GetRelease(repo.ID, tagName) if err != nil { if IsErrReleaseNotExist(err) { @@ -409,7 +439,7 @@ func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { } // SaveOrUpdateTag must be called for any push actions to add tag -func SaveOrUpdateTag(repo *repo_model.Repository, newRel *Release) error { +func SaveOrUpdateTag(repo *Repository, newRel *Release) error { rel, err := GetRelease(repo.ID, newRel.TagName) if err != nil && !IsErrReleaseNotExist(err) { return fmt.Errorf("GetRelease: %v", err) diff --git a/models/repo/repo.go b/models/repo/repo.go index bb2a7468f..9a582c8fe 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -23,6 +23,8 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" ) // ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. @@ -784,3 +786,15 @@ func UpdateRepoIssueNumbers(ctx context.Context, repoID int64, isPull, isClosed } return nil } + +// CountNullArchivedRepository counts the number of repositories with is_archived is null +func CountNullArchivedRepository() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(Repository)) +} + +// FixNullArchivedRepository sets is_archived to false where it is null +func FixNullArchivedRepository() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&Repository{ + IsArchived: false, + }) +} diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 1fa469fcf..ee72dc6ee 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -163,6 +163,10 @@ type SearchRepoOptions struct { HasMilestones util.OptionalBool // LowerNames represents valid lower names to restrict to LowerNames []string + // When specified true, apply some filters over the conditions: + // - Don't show forks, when opts.Fork is OptionalBoolNone. + // - Do not display repositories that don't have a description, an icon and topics. + OnlyShowRelevant bool } // SearchOrderBy is used to sort the result @@ -463,8 +467,12 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true}))) } - if opts.Fork != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue}) + if opts.Fork != util.OptionalBoolNone || opts.OnlyShowRelevant { + if opts.OnlyShowRelevant && opts.Fork == util.OptionalBoolNone { + cond = cond.And(builder.Eq{"is_fork": false}) + } else { + cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue}) + } } if opts.Mirror != util.OptionalBoolNone { @@ -486,6 +494,25 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"})) } + if opts.OnlyShowRelevant { + // Only show a repo that either has a topic or description. + subQueryCond := builder.NewCond() + + // Topic checking. Topics is non-null. + subQueryCond = subQueryCond.Or(builder.And(builder.Neq{"topics": "null"}, builder.Neq{"topics": "[]"})) + + // Description checking. Description not empty. + subQueryCond = subQueryCond.Or(builder.Neq{"description": ""}) + + // Repo has a avatar. + subQueryCond = subQueryCond.Or(builder.Neq{"avatar": ""}) + + // Always hide repo's that are empty. + subQueryCond = subQueryCond.And(builder.Eq{"is_empty": false}) + + cond = cond.And(subQueryCond) + } + return cond } diff --git a/models/upload.go b/models/repo/upload.go similarity index 88% rename from models/upload.go rename to models/repo/upload.go index 4a64ff34e..24544910b 100644 --- a/models/upload.go +++ b/models/repo/upload.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package repo import ( "fmt" @@ -20,13 +20,21 @@ import ( gouuid "github.com/google/uuid" ) -// ____ ___ .__ .___ ___________.___.__ -// | | \______ | | _________ __| _/ \_ _____/| | | ____ ______ -// | | /\____ \| | / _ \__ \ / __ | | __) | | | _/ __ \ / ___/ -// | | / | |_> > |_( <_> ) __ \_/ /_/ | | \ | | |_\ ___/ \___ \ -// |______/ | __/|____/\____(____ /\____ | \___ / |___|____/\___ >____ > -// |__| \/ \/ \/ \/ \/ -// +// ErrUploadNotExist represents a "UploadNotExist" kind of error. +type ErrUploadNotExist struct { + ID int64 + UUID string +} + +// IsErrUploadNotExist checks if an error is a ErrUploadNotExist. +func IsErrUploadNotExist(err error) bool { + _, ok := err.(ErrUploadNotExist) + return ok +} + +func (err ErrUploadNotExist) Error() string { + return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) +} // Upload represent a uploaded file to a repo to be deleted when moved type Upload struct { diff --git a/models/repo/wiki.go b/models/repo/wiki.go index abf0155ca..72ec7c394 100644 --- a/models/repo/wiki.go +++ b/models/repo/wiki.go @@ -6,6 +6,7 @@ package repo import ( + "fmt" "path/filepath" "strings" @@ -14,6 +15,51 @@ import ( "code.gitea.io/gitea/modules/util" ) +// ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error. +type ErrWikiAlreadyExist struct { + Title string +} + +// IsErrWikiAlreadyExist checks if an error is an ErrWikiAlreadyExist. +func IsErrWikiAlreadyExist(err error) bool { + _, ok := err.(ErrWikiAlreadyExist) + return ok +} + +func (err ErrWikiAlreadyExist) Error() string { + return fmt.Sprintf("wiki page already exists [title: %s]", err.Title) +} + +// ErrWikiReservedName represents a reserved name error. +type ErrWikiReservedName struct { + Title string +} + +// IsErrWikiReservedName checks if an error is an ErrWikiReservedName. +func IsErrWikiReservedName(err error) bool { + _, ok := err.(ErrWikiReservedName) + return ok +} + +func (err ErrWikiReservedName) Error() string { + return fmt.Sprintf("wiki title is reserved: %s", err.Title) +} + +// ErrWikiInvalidFileName represents an invalid wiki file name. +type ErrWikiInvalidFileName struct { + FileName string +} + +// IsErrWikiInvalidFileName checks if an error is an ErrWikiInvalidFileName. +func IsErrWikiInvalidFileName(err error) bool { + _, ok := err.(ErrWikiInvalidFileName) + return ok +} + +func (err ErrWikiInvalidFileName) Error() string { + return fmt.Sprintf("Invalid wiki filename: %s", err.FileName) +} + // WikiCloneLink returns clone URLs of repository wiki. func (repo *Repository) WikiCloneLink() *CloneLink { return repo.cloneLink(true) diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index c8866421b..05df2f29a 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -19,42 +18,6 @@ import ( "xorm.io/builder" ) -func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { - collaboration := &repo_model.Collaboration{ - RepoID: repo.ID, - UserID: u.ID, - } - - has, err := db.GetByBean(ctx, collaboration) - if err != nil { - return err - } else if has { - return nil - } - collaboration.Mode = perm.AccessModeWrite - - if err = db.Insert(ctx, collaboration); err != nil { - return err - } - - return access_model.RecalculateUserAccess(ctx, repo, u.ID) -} - -// AddCollaborator adds new collaboration to a repository with default access mode. -func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := addCollaborator(ctx, repo, u); err != nil { - return err - } - - return committer.Commit() -} - // DeleteCollaboration removes collaboration relation between the user and repository. func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { collaboration := &repo_model.Collaboration{ diff --git a/models/repo_collaboration_test.go b/models/repo_collaboration_test.go index 72b354f1a..77034b65d 100644 --- a/models/repo_collaboration_test.go +++ b/models/repo_collaboration_test.go @@ -10,26 +10,10 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" "github.com/stretchr/testify/assert" ) -func TestRepository_AddCollaborator(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - testSuccess := func(repoID, userID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - assert.NoError(t, repo.GetOwner(db.DefaultContext)) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) - assert.NoError(t, AddCollaborator(repo, user)) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) - } - testSuccess(1, 4) - testSuccess(1, 4) - testSuccess(3, 4) -} - func TestRepository_DeleteCollaboration(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) diff --git a/models/repo_transfer.go b/models/repo_transfer.go index 7d07fb252..636d49b98 100644 --- a/models/repo_transfer.go +++ b/models/repo_transfer.go @@ -327,8 +327,8 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo } for _, t := range teams { if t.IncludesAllRepositories { - if err := addRepository(ctx, t, repo); err != nil { - return fmt.Errorf("addRepository: %v", err) + if err := AddRepository(ctx, t, repo); err != nil { + return fmt.Errorf("AddRepository: %v", err) } } } diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index 58656f781..25129137f 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -116,7 +116,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) { if err = util.RemoveAll(repoRootPath); err != nil { fatalTestError("util.RemoveAll: %v\n", err) } - if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil { + if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "tests", "gitea-repositories-meta"), setting.RepoRootPath); err != nil { fatalTestError("util.CopyDir: %v\n", err) } @@ -202,7 +202,7 @@ func PrepareTestDatabase() error { func PrepareTestEnv(t testing.TB) { assert.NoError(t, PrepareTestDatabase()) assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) - metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta") + metaPath := filepath.Join(giteaRoot, "tests", "gitea-repositories-meta") assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath)) ownerDirs, err := os.ReadDir(setting.RepoRootPath) assert.NoError(t, err) diff --git a/models/user.go b/models/user.go index 4afbb9bea..68be0d855 100644 --- a/models/user.go +++ b/models/user.go @@ -12,6 +12,7 @@ import ( _ "image/jpeg" // Needed for jpeg support + activities_model "code.gitea.io/gitea/models/activities" asymkey_model "code.gitea.io/gitea/models/asymkey" auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" @@ -70,14 +71,14 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) // ***** END: Follow ***** if err = db.DeleteBeans(ctx, - &AccessToken{UID: u.ID}, + &auth_model.AccessToken{UID: u.ID}, &repo_model.Collaboration{UserID: u.ID}, &access_model.Access{UserID: u.ID}, &repo_model.Watch{UserID: u.ID}, &repo_model.Star{UID: u.ID}, &user_model.Follow{UserID: u.ID}, &user_model.Follow{FollowID: u.ID}, - &Action{UserID: u.ID}, + &activities_model.Action{UserID: u.ID}, &issues_model.IssueUser{UID: u.ID}, &user_model.EmailAddress{UID: u.ID}, &user_model.UserOpenID{UID: u.ID}, @@ -101,9 +102,9 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) // Delete Comments const batchSize = 50 - for start := 0; ; start += batchSize { + for { comments := make([]*issues_model.Comment, 0, batchSize) - if err = e.Where("type=? AND poster_id=?", issues_model.CommentTypeComment, u.ID).Limit(batchSize, start).Find(&comments); err != nil { + if err = e.Where("type=? AND poster_id=?", issues_model.CommentTypeComment, u.ID).Limit(batchSize, 0).Find(&comments); err != nil { return err } if len(comments) == 0 { @@ -201,7 +202,7 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) // ***** END: ExternalLoginUser ***** if _, err = e.ID(u.ID).Delete(new(user_model.User)); err != nil { - return fmt.Errorf("Delete: %v", err) + return fmt.Errorf("delete: %v", err) } return nil diff --git a/models/user/user.go b/models/user/user.go index 91eeeb896..f1df335eb 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -1317,6 +1317,16 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool { return false } +// CountWrongUserType count OrgUser who have wrong type +func CountWrongUserType() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(User)) +} + +// FixWrongUserType fix OrgUser who have wrong type +func FixWrongUserType() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1}) +} + func GetOrderByName() string { if setting.UI.DefaultShowFullName { return "full_name, name" diff --git a/models/user/user_update.go b/models/user/user_update.go new file mode 100644 index 000000000..9c9dc09bb --- /dev/null +++ b/models/user/user_update.go @@ -0,0 +1,16 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package user + +import ( + "context" + + "code.gitea.io/gitea/models/db" +) + +func IncrUserRepoNum(ctx context.Context, userID int64) error { + _, err := db.GetEngine(ctx).Incr("num_repos").ID(userID).Update(new(User)) + return err +} diff --git a/models/webhook/hooktask.go b/models/webhook/hooktask.go index 4415518cf..2adfcaa60 100644 --- a/models/webhook/hooktask.go +++ b/models/webhook/hooktask.go @@ -47,6 +47,7 @@ const ( HookEventPullRequestReviewRejected HookEventType = "pull_request_review_rejected" HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment" HookEventPullRequestSync HookEventType = "pull_request_sync" + HookEventWiki HookEventType = "wiki" HookEventRepository HookEventType = "repository" HookEventRelease HookEventType = "release" HookEventPackage HookEventType = "package" @@ -76,6 +77,8 @@ func (h HookEventType) Event() string { return "pull_request_rejected" case HookEventPullRequestReviewComment: return "pull_request_comment" + case HookEventWiki: + return "wiki" case HookEventRepository: return "repository" case HookEventRelease: diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go index 478a6a29f..ac0922063 100644 --- a/models/webhook/webhook.go +++ b/models/webhook/webhook.go @@ -132,6 +132,7 @@ type HookEvents struct { PullRequestComment bool `json:"pull_request_comment"` PullRequestReview bool `json:"pull_request_review"` PullRequestSync bool `json:"pull_request_sync"` + Wiki bool `json:"wiki"` Repository bool `json:"repository"` Release bool `json:"release"` Package bool `json:"package"` @@ -328,6 +329,12 @@ func (w *Webhook) HasPullRequestSyncEvent() bool { (w.ChooseEvents && w.HookEvents.PullRequestSync) } +// HasWikiEvent returns true if hook enabled wiki event. +func (w *Webhook) HasWikiEvent() bool { + return w.SendEverything || + (w.ChooseEvents && w.HookEvent.Wiki) +} + // HasReleaseEvent returns if hook enabled release event. func (w *Webhook) HasReleaseEvent() bool { return w.SendEverything || @@ -373,6 +380,7 @@ func (w *Webhook) EventCheckers() []struct { {w.HasPullRequestRejectedEvent, HookEventPullRequestReviewRejected}, {w.HasPullRequestCommentEvent, HookEventPullRequestReviewComment}, {w.HasPullRequestSyncEvent, HookEventPullRequestSync}, + {w.HasWikiEvent, HookEventWiki}, {w.HasRepositoryEvent, HookEventRepository}, {w.HasReleaseEvent, HookEventRelease}, {w.HasPackageEvent, HookEventPackage}, diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index 1d77ee2a4..7ec7edc0b 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -71,7 +71,7 @@ func TestWebhook_EventsArray(t *testing.T) { "issues", "issue_assign", "issue_label", "issue_milestone", "issue_comment", "pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone", "pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected", - "pull_request_review_comment", "pull_request_sync", "repository", "release", + "pull_request_review_comment", "pull_request_sync", "wiki", "repository", "release", "package", }, (&Webhook{ diff --git a/modules/avatar/identicon/block.go b/modules/avatar/identicon/block.go index 249a3e095..270f05e1b 100644 --- a/modules/avatar/identicon/block.go +++ b/modules/avatar/identicon/block.go @@ -36,20 +36,20 @@ func drawBlock(img *image.Paletted, x, y, size, angle int, points []int) { // blank // -// -------- -// | | -// | | -// | | -// -------- +// -------- +// | | +// | | +// | | +// -------- func b0(img *image.Paletted, x, y, size, angle int) {} // full-filled // -// -------- -// |######| -// |######| -// |######| -// -------- +// -------- +// |######| +// |######| +// |######| +// -------- func b1(img *image.Paletted, x, y, size, angle int) { for i := x; i < x+size; i++ { for j := y; j < y+size; j++ { @@ -59,12 +59,13 @@ func b1(img *image.Paletted, x, y, size, angle int) { } // a small block -// ---------- -// | | -// | #### | -// | #### | -// | | -// ---------- +// +// ---------- +// | | +// | #### | +// | #### | +// | | +// ---------- func b2(img *image.Paletted, x, y, size, angle int) { l := size / 4 x += l @@ -79,15 +80,15 @@ func b2(img *image.Paletted, x, y, size, angle int) { // diamond // -// --------- -// | # | -// | ### | -// | ##### | -// |#######| -// | ##### | -// | ### | -// | # | -// --------- +// --------- +// | # | +// | ### | +// | ##### | +// |#######| +// | ##### | +// | ### | +// | # | +// --------- func b3(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, 0, []int{ @@ -101,13 +102,13 @@ func b3(img *image.Paletted, x, y, size, angle int) { // b4 // -// ------- -// |#####| -// |#### | -// |### | -// |## | -// |# | -// |------ +// ------- +// |#####| +// |#### | +// |### | +// |## | +// |# | +// |------ func b4(img *image.Paletted, x, y, size, angle int) { drawBlock(img, x, y, size, angle, []int{ 0, 0, @@ -119,11 +120,11 @@ func b4(img *image.Paletted, x, y, size, angle int) { // b5 // -// --------- -// | # | -// | ### | -// | ##### | -// |#######| +// --------- +// | # | +// | ### | +// | ##### | +// |#######| func b5(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -136,11 +137,11 @@ func b5(img *image.Paletted, x, y, size, angle int) { // b6 // -// -------- -// |### | -// |### | -// |### | -// -------- +// -------- +// |### | +// |### | +// |### | +// -------- func b6(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -154,12 +155,12 @@ func b6(img *image.Paletted, x, y, size, angle int) { // b7 italic cone // -// --------- -// | # | -// | ## | -// | #####| -// | ####| -// |-------- +// --------- +// | # | +// | ## | +// | #####| +// | ####| +// |-------- func b7(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -173,14 +174,14 @@ func b7(img *image.Paletted, x, y, size, angle int) { // b8 three small triangles // -// ----------- -// | # | -// | ### | -// | ##### | -// | # # | -// | ### ### | -// |#########| -// ----------- +// ----------- +// | # | +// | ### | +// | ##### | +// | # # | +// | ### ### | +// |#########| +// ----------- func b8(img *image.Paletted, x, y, size, angle int) { m := size / 2 mm := m / 2 @@ -212,13 +213,13 @@ func b8(img *image.Paletted, x, y, size, angle int) { // b9 italic triangle // -// --------- -// |# | -// | #### | -// | #####| -// | #### | -// | # | -// --------- +// --------- +// |# | +// | #### | +// | #####| +// | #### | +// | # | +// --------- func b9(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -231,16 +232,16 @@ func b9(img *image.Paletted, x, y, size, angle int) { // b10 // -// ---------- -// | ####| -// | ### | -// | ## | -// | # | -// |#### | -// |### | -// |## | -// |# | -// ---------- +// ---------- +// | ####| +// | ### | +// | ## | +// | # | +// |#### | +// |### | +// |## | +// |# | +// ---------- func b10(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -260,13 +261,13 @@ func b10(img *image.Paletted, x, y, size, angle int) { // b11 // -// ---------- -// |#### | -// |#### | -// |#### | -// | | -// | | -// ---------- +// ---------- +// |#### | +// |#### | +// |#### | +// | | +// | | +// ---------- func b11(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -280,13 +281,13 @@ func b11(img *image.Paletted, x, y, size, angle int) { // b12 // -// ----------- -// | | -// | | -// |#########| -// | ##### | -// | # | -// ----------- +// ----------- +// | | +// | | +// |#########| +// | ##### | +// | # | +// ----------- func b12(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -299,13 +300,13 @@ func b12(img *image.Paletted, x, y, size, angle int) { // b13 // -// ----------- -// | | -// | | -// | # | -// | ##### | -// |#########| -// ----------- +// ----------- +// | | +// | | +// | # | +// | ##### | +// |#########| +// ----------- func b13(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -318,13 +319,13 @@ func b13(img *image.Paletted, x, y, size, angle int) { // b14 // -// --------- -// | # | -// | ### | -// |#### | -// | | -// | | -// --------- +// --------- +// | # | +// | ### | +// |#### | +// | | +// | | +// --------- func b14(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -337,13 +338,13 @@ func b14(img *image.Paletted, x, y, size, angle int) { // b15 // -// ---------- -// |##### | -// |### | -// |# | -// | | -// | | -// ---------- +// ---------- +// |##### | +// |### | +// |# | +// | | +// | | +// ---------- func b15(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -356,14 +357,14 @@ func b15(img *image.Paletted, x, y, size, angle int) { // b16 // -// --------- -// | # | -// | ##### | -// |#######| -// | # | -// | ##### | -// |#######| -// --------- +// --------- +// | # | +// | ##### | +// |#######| +// | # | +// | ##### | +// |#######| +// --------- func b16(img *image.Paletted, x, y, size, angle int) { m := size / 2 drawBlock(img, x, y, size, angle, []int{ @@ -383,13 +384,13 @@ func b16(img *image.Paletted, x, y, size, angle int) { // b17 // -// ---------- -// |##### | -// |### | -// |# | -// | ##| -// | ##| -// ---------- +// ---------- +// |##### | +// |### | +// |# | +// | ##| +// | ##| +// ---------- func b17(img *image.Paletted, x, y, size, angle int) { m := size / 2 @@ -412,13 +413,13 @@ func b17(img *image.Paletted, x, y, size, angle int) { // b18 // -// ---------- -// |##### | -// |#### | -// |### | -// |## | -// |# | -// ---------- +// ---------- +// |##### | +// |#### | +// |### | +// |## | +// |# | +// ---------- func b18(img *image.Paletted, x, y, size, angle int) { m := size / 2 @@ -432,13 +433,13 @@ func b18(img *image.Paletted, x, y, size, angle int) { // b19 // -// ---------- -// |########| -// |### ###| -// |# #| -// |### ###| -// |########| -// ---------- +// ---------- +// |########| +// |### ###| +// |# #| +// |### ###| +// |########| +// ---------- func b19(img *image.Paletted, x, y, size, angle int) { m := size / 2 @@ -473,13 +474,13 @@ func b19(img *image.Paletted, x, y, size, angle int) { // b20 // -// ---------- -// | ## | -// |### | -// |## | -// |## | -// |# | -// ---------- +// ---------- +// | ## | +// |### | +// |## | +// |## | +// |# | +// ---------- func b20(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -494,13 +495,13 @@ func b20(img *image.Paletted, x, y, size, angle int) { // b21 // -// ---------- -// | #### | -// |## #####| -// |## ##| -// |## | -// |# | -// ---------- +// ---------- +// | #### | +// |## #####| +// |## ##| +// |## | +// |# | +// ---------- func b21(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -522,13 +523,13 @@ func b21(img *image.Paletted, x, y, size, angle int) { // b22 // -// ---------- -// | #### | -// |## ### | -// |## ##| -// |## ##| -// |# #| -// ---------- +// ---------- +// | #### | +// |## ### | +// |## ##| +// |## ##| +// |# #| +// ---------- func b22(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -550,13 +551,13 @@ func b22(img *image.Paletted, x, y, size, angle int) { // b23 // -// ---------- -// | #######| -// |### #| -// |## | -// |## | -// |# | -// ---------- +// ---------- +// | #######| +// |### #| +// |## | +// |## | +// |# | +// ---------- func b23(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -578,13 +579,13 @@ func b23(img *image.Paletted, x, y, size, angle int) { // b24 // -// ---------- -// | ## ###| -// |### ###| -// |## ## | -// |## ## | -// |# # | -// ---------- +// ---------- +// | ## ###| +// |### ###| +// |## ## | +// |## ## | +// |# # | +// ---------- func b24(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -606,13 +607,13 @@ func b24(img *image.Paletted, x, y, size, angle int) { // b25 // -// ---------- -// |# #| -// |## ###| -// |## ## | -// |###### | -// |#### | -// ---------- +// ---------- +// |# #| +// |## ###| +// |## ## | +// |###### | +// |#### | +// ---------- func b25(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -634,13 +635,13 @@ func b25(img *image.Paletted, x, y, size, angle int) { // b26 // -// ---------- -// |# #| -// |### ###| -// | #### | -// |### ###| -// |# #| -// ---------- +// ---------- +// |# #| +// |### ###| +// | #### | +// |### ###| +// |# #| +// ---------- func b26(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 @@ -676,13 +677,13 @@ func b26(img *image.Paletted, x, y, size, angle int) { // b27 // -// ---------- -// |########| -// |## ###| -// |# #| -// |### ##| -// |########| -// ---------- +// ---------- +// |########| +// |## ###| +// |# #| +// |### ##| +// |########| +// ---------- func b27(img *image.Paletted, x, y, size, angle int) { m := size / 2 q := size / 4 diff --git a/modules/charset/ambiguous/generate.go b/modules/charset/ambiguous/generate.go index 43cdb217a..7dd2821aa 100644 --- a/modules/charset/ambiguous/generate.go +++ b/modules/charset/ambiguous/generate.go @@ -110,6 +110,17 @@ func runTemplate(t *template.Template, filename string, data interface{}) error verbosef("Bad source:\n%s", buf.String()) return fmt.Errorf("unable to format source: %w", err) } + + old, err := os.ReadFile(filename) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to read old file %s because %w", filename, err) + } else if err == nil { + if bytes.Equal(bs, old) { + // files are the same don't rewrite it. + return nil + } + } + file, err := os.Create(filename) if err != nil { return fmt.Errorf("failed to create file %s because %w", filename, err) diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index 8c17136c9..e5f303d26 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -50,6 +50,7 @@ func (e *escapeStreamer) Text(data string) error { _, _ = sb.WriteString(data[:len(UTF8BOM)]) pos = len(UTF8BOM) } + dataBytes := []byte(data) for pos < len(data) { nextIdxs := defaultWordRegexp.FindStringIndex(data[pos:]) if nextIdxs == nil { @@ -64,18 +65,18 @@ func (e *escapeStreamer) Text(data string) error { positions := make([]int, 0, next-until+1) for pos < until { - r, sz := utf8.DecodeRune([]byte(data)[pos:]) + r, sz := utf8.DecodeRune(dataBytes[pos:]) positions = positions[:0] positions = append(positions, pos, pos+sz) types, confusables, _ := e.runeTypes(r) - if err := e.handleRunes(data, []rune{r}, positions, types, confusables, sb); err != nil { + if err := e.handleRunes(dataBytes, []rune{r}, positions, types, confusables, sb); err != nil { return err } pos += sz } for i := pos; i < next; { - r, sz := utf8.DecodeRune([]byte(data)[i:]) + r, sz := utf8.DecodeRune(dataBytes[i:]) runes = append(runes, r) positions = append(positions, i) i += sz @@ -83,11 +84,11 @@ func (e *escapeStreamer) Text(data string) error { positions = append(positions, next) types, confusables, runeCounts := e.runeTypes(runes...) if runeCounts.needsEscape() { - if err := e.handleRunes(data, runes, positions, types, confusables, sb); err != nil { + if err := e.handleRunes(dataBytes, runes, positions, types, confusables, sb); err != nil { return err } } else { - _, _ = sb.Write([]byte(data)[pos:next]) + _, _ = sb.Write(dataBytes[pos:next]) } pos = next } @@ -99,7 +100,7 @@ func (e *escapeStreamer) Text(data string) error { return nil } -func (e *escapeStreamer) handleRunes(data string, runes []rune, positions []int, types []runeType, confusables []rune, sb *strings.Builder) error { +func (e *escapeStreamer) handleRunes(data []byte, runes []rune, positions []int, types []runeType, confusables []rune, sb *strings.Builder) error { for i, r := range runes { switch types[i] { case brokenRuneType: @@ -111,7 +112,7 @@ func (e *escapeStreamer) handleRunes(data string, runes []rune, positions []int, } end := positions[i+1] start := positions[i] - if err := e.brokenRune([]byte(data)[start:end]); err != nil { + if err := e.brokenRune(data[start:end]); err != nil { return err } case ambiguousRuneType: diff --git a/modules/charset/escape_test.go b/modules/charset/escape_test.go index 8063e1154..a7232a465 100644 --- a/modules/charset/escape_test.go +++ b/modules/charset/escape_test.go @@ -133,11 +133,18 @@ then resh (ืจ), and finally heh (ื”) (which should appear leftmost).`, }, } +type nullLocale struct{} + +func (nullLocale) Language() string { return "" } +func (nullLocale) Tr(key string, _ ...interface{}) string { return key } +func (nullLocale) TrN(cnt interface{}, key1, keyN string, args ...interface{}) string { return "" } + +var _ (translation.Locale) = nullLocale{} + func TestEscapeControlString(t *testing.T) { for _, tt := range escapeControlTests { t.Run(tt.name, func(t *testing.T) { - locale := translation.NewLocale("en_US") - status, result := EscapeControlString(tt.text, locale) + status, result := EscapeControlString(tt.text, nullLocale{}) if !reflect.DeepEqual(*status, tt.status) { t.Errorf("EscapeControlString() status = %v, wanted= %v", status, tt.status) } @@ -173,7 +180,7 @@ func TestEscapeControlReader(t *testing.T) { t.Run(tt.name, func(t *testing.T) { input := strings.NewReader(tt.text) output := &strings.Builder{} - status, err := EscapeControlReader(input, output, translation.NewLocale("en_US")) + status, err := EscapeControlReader(input, output, nullLocale{}) result := output.String() if err != nil { t.Errorf("EscapeControlReader(): err = %v", err) @@ -195,5 +202,5 @@ func TestEscapeControlReader_panic(t *testing.T) { for i := 0; i < 6826; i++ { bs = append(bs, []byte("โ€”")...) } - _, _ = EscapeControlString(string(bs), translation.NewLocale("en_US")) + _, _ = EscapeControlString(string(bs), nullLocale{}) } diff --git a/modules/charset/invisible/generate.go b/modules/charset/invisible/generate.go index 230ff0b83..39eddd58d 100644 --- a/modules/charset/invisible/generate.go +++ b/modules/charset/invisible/generate.go @@ -63,6 +63,17 @@ func runTemplate(t *template.Template, filename string, data interface{}) error verbosef("Bad source:\n%s", buf.String()) return fmt.Errorf("unable to format source: %w", err) } + + old, err := os.ReadFile(filename) + if err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to read old file %s because %w", filename, err) + } else if err == nil { + if bytes.Equal(bs, old) { + // files are the same don't rewrite it. + return nil + } + } + file, err := os.Create(filename) if err != nil { return fmt.Errorf("failed to create file %s because %w", filename, err) diff --git a/modules/context/context.go b/modules/context/context.go index 0b9898ace..4b6a21b21 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -358,14 +358,7 @@ func (ctx *Context) SetServeHeaders(filename string) { } // ServeContent serves content to http request -func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) { - modTime := time.Now() - for _, p := range params { - switch v := p.(type) { - case time.Time: - modTime = v - } - } +func (ctx *Context) ServeContent(name string, r io.ReadSeeker, modTime time.Time) { ctx.SetServeHeaders(name) http.ServeContent(ctx.Resp, ctx.Req, name, modTime, r) } @@ -382,15 +375,6 @@ func (ctx *Context) ServeFile(file string, names ...string) { http.ServeFile(ctx.Resp, ctx.Req, file) } -// ServeStream serves file via io stream -func (ctx *Context) ServeStream(rd io.Reader, name string) { - ctx.SetServeHeaders(name) - _, err := io.Copy(ctx.Resp, rd) - if err != nil { - ctx.ServerError("Download file failed", err) - } -} - // UploadStream returns the request body or the first form file // Only form files need to get closed. func (ctx *Context) UploadStream() (rd io.ReadCloser, needToClose bool, err error) { @@ -674,8 +658,8 @@ func Auth(authMethod auth.Method) func(*Context) { } // Contexter initializes a classic context for a request. -func Contexter() func(next http.Handler) http.Handler { - rnd := templates.HTMLRenderer() +func Contexter(ctx context.Context) func(next http.Handler) http.Handler { + _, rnd := templates.HTMLRenderer(ctx) csrfOpts := getCsrfOpts() if !setting.IsProd { CsrfTokenRegenerationInterval = 5 * time.Second // in dev, re-generate the tokens more aggressively for debug purpose diff --git a/modules/context/package.go b/modules/context/package.go index 92a97831d..ad06f4d63 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -5,6 +5,7 @@ package context import ( + gocontext "context" "fmt" "net/http" @@ -14,6 +15,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/templates" ) // Package contains owner, access mode and optional the package descriptor @@ -118,12 +120,14 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) { } // PackageContexter initializes a package context for a request. -func PackageContexter() func(next http.Handler) http.Handler { +func PackageContexter(ctx gocontext.Context) func(next http.Handler) http.Handler { + _, rnd := templates.HTMLRenderer(ctx) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { ctx := Context{ - Resp: NewResponse(resp), - Data: map[string]interface{}{}, + Resp: NewResponse(resp), + Data: map[string]interface{}{}, + Render: rnd, } defer ctx.Close() diff --git a/modules/context/repo.go b/modules/context/repo.go index ea4054206..6a336c45f 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "html" - "io" "net/http" "net/url" "path" @@ -26,8 +25,8 @@ import ( "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" code_indexer "code.gitea.io/gitea/modules/indexer/code" + "code.gitea.io/gitea/modules/issue/template" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/markup/markdown" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" @@ -118,7 +117,8 @@ type CanCommitToBranchResults struct { } // CanCommitToBranch returns true if repository is editable and user has proper access level -// and branch is not protected for push +// +// and branch is not protected for push func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) { protectedBranch, err := git_model.GetProtectedBranchBy(ctx, r.Repository.ID, r.BranchName) if err != nil { @@ -523,14 +523,14 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL } - ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{ + ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ IncludeTags: true, }) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) return } - ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{}) + ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{}) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) return @@ -986,6 +986,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context } ctx.Data["BranchName"] = ctx.Repo.BranchName + ctx.Data["RefName"] = ctx.Repo.RefName ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() ctx.Data["TagName"] = ctx.Repo.TagName ctx.Data["CommitID"] = ctx.Repo.CommitID @@ -1032,70 +1033,52 @@ func UnitTypes() func(ctx *Context) { } } -// IssueTemplatesFromDefaultBranch checks for issue templates in the repo's default branch -func (ctx *Context) IssueTemplatesFromDefaultBranch() []api.IssueTemplate { - var issueTemplates []api.IssueTemplate +// IssueTemplatesFromDefaultBranch checks for valid issue templates in the repo's default branch, +func (ctx *Context) IssueTemplatesFromDefaultBranch() []*api.IssueTemplate { + ret, _ := ctx.IssueTemplatesErrorsFromDefaultBranch() + return ret +} + +// IssueTemplatesErrorsFromDefaultBranch checks for issue templates in the repo's default branch, +// returns valid templates and the errors of invalid template files. +func (ctx *Context) IssueTemplatesErrorsFromDefaultBranch() ([]*api.IssueTemplate, map[string]error) { + var issueTemplates []*api.IssueTemplate if ctx.Repo.Repository.IsEmpty { - return issueTemplates + return issueTemplates, nil } if ctx.Repo.Commit == nil { var err error ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { - return issueTemplates + return issueTemplates, nil } } + invalidFiles := map[string]error{} for _, dirName := range IssueTemplateDirCandidates { tree, err := ctx.Repo.Commit.SubTree(dirName) if err != nil { + log.Debug("get sub tree of %s: %v", dirName, err) continue } entries, err := tree.ListEntries() if err != nil { - return issueTemplates + log.Debug("list entries in %s: %v", dirName, err) + return issueTemplates, nil } for _, entry := range entries { - if strings.HasSuffix(entry.Name(), ".md") { - if entry.Blob().Size() >= setting.UI.MaxDisplayFileSize { - log.Debug("Issue template is too large: %s", entry.Name()) - continue - } - r, err := entry.Blob().DataAsync() - if err != nil { - log.Debug("DataAsync: %v", err) - continue - } - closed := false - defer func() { - if !closed { - _ = r.Close() - } - }() - data, err := io.ReadAll(r) - if err != nil { - log.Debug("ReadAll: %v", err) - continue - } - _ = r.Close() - var it api.IssueTemplate - content, err := markdown.ExtractMetadata(string(data), &it) - if err != nil { - log.Debug("ExtractMetadata: %v", err) - continue - } - it.Content = content - it.FileName = entry.Name() - if it.Valid() { - issueTemplates = append(issueTemplates, it) - } + if !template.CouldBe(entry.Name()) { + continue + } + fullName := path.Join(dirName, entry.Name()) + if it, err := template.UnmarshalFromEntry(entry, dirName); err != nil { + invalidFiles[fullName] = err + } else { + issueTemplates = append(issueTemplates, it) } } - if len(issueTemplates) > 0 { - return issueTemplates - } } - return issueTemplates + return issueTemplates, invalidFiles } diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index ccc94b249..73ad345fa 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -101,6 +101,12 @@ func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.Time } if c.Time != nil { + err = c.Time.LoadAttributes() + if err != nil { + log.Error("Time.LoadAttributes: %v", err) + return nil + } + comment.TrackedTime = ToTrackedTime(c.Time) } diff --git a/modules/convert/notification.go b/modules/convert/notification.go index 1efba5745..55f782f8f 100644 --- a/modules/convert/notification.go +++ b/modules/convert/notification.go @@ -7,17 +7,17 @@ package convert import ( "net/url" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/perm" api "code.gitea.io/gitea/modules/structs" ) // ToNotificationThread convert a Notification to api.NotificationThread -func ToNotificationThread(n *models.Notification) *api.NotificationThread { +func ToNotificationThread(n *activities_model.Notification) *api.NotificationThread { result := &api.NotificationThread{ ID: n.ID, - Unread: !(n.Status == models.NotificationStatusRead || n.Status == models.NotificationStatusPinned), - Pinned: n.Status == models.NotificationStatusPinned, + Unread: !(n.Status == activities_model.NotificationStatusRead || n.Status == activities_model.NotificationStatusPinned), + Pinned: n.Status == activities_model.NotificationStatusPinned, UpdatedAt: n.UpdatedUnix.AsTime(), URL: n.APIURL(), } @@ -34,7 +34,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { // handle Subject switch n.Source { - case models.NotificationSourceIssue: + case activities_model.NotificationSourceIssue: result.Subject = &api.NotificationSubject{Type: api.NotifySubjectIssue} if n.Issue != nil { result.Subject.Title = n.Issue.Title @@ -47,7 +47,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { result.Subject.LatestCommentHTMLURL = comment.HTMLURL() } } - case models.NotificationSourcePullRequest: + case activities_model.NotificationSourcePullRequest: result.Subject = &api.NotificationSubject{Type: api.NotifySubjectPull} if n.Issue != nil { result.Subject.Title = n.Issue.Title @@ -65,7 +65,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { result.Subject.State = "merged" } } - case models.NotificationSourceCommit: + case activities_model.NotificationSourceCommit: url := n.Repository.HTMLURL() + "/commit/" + url.PathEscape(n.CommitID) result.Subject = &api.NotificationSubject{ Type: api.NotifySubjectCommit, @@ -73,7 +73,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { URL: url, HTMLURL: url, } - case models.NotificationSourceRepository: + case activities_model.NotificationSourceRepository: result.Subject = &api.NotificationSubject{ Type: api.NotifySubjectRepository, Title: n.Repository.FullName(), @@ -87,7 +87,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { } // ToNotifications convert list of Notification to api.NotificationThread list -func ToNotifications(nl models.NotificationList) []*api.NotificationThread { +func ToNotifications(nl activities_model.NotificationList) []*api.NotificationThread { result := make([]*api.NotificationThread, 0, len(nl)) for _, n := range nl { result = append(result, ToNotificationThread(n)) diff --git a/modules/convert/release.go b/modules/convert/release.go index 955d3ff05..5fc95dab7 100644 --- a/modules/convert/release.go +++ b/modules/convert/release.go @@ -5,13 +5,12 @@ package convert import ( - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" api "code.gitea.io/gitea/modules/structs" ) -// ToRelease convert a models.Release to api.Release -func ToRelease(r *models.Release) *api.Release { +// ToRelease convert a repo_model.Release to api.Release +func ToRelease(r *repo_model.Release) *api.Release { assets := make([]*api.Attachment, 0) for _, att := range r.Attachments { assets = append(assets, ToReleaseAttachment(att)) diff --git a/modules/convert/repository.go b/modules/convert/repository.go index d333c124b..f85316384 100644 --- a/modules/convert/repository.go +++ b/modules/convert/repository.go @@ -102,7 +102,7 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo return nil } - numReleases, _ := models.GetReleaseCountByRepoID(repo.ID, models.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false}) + numReleases, _ := repo_model.GetReleaseCountByRepoID(repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false}) mirrorInterval := "" var mirrorUpdated time.Time diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go index 9d0848ae5..5a8e13c81 100644 --- a/modules/csv/csv_test.go +++ b/modules/csv/csv_test.go @@ -322,7 +322,7 @@ func TestGuessDelimiter(t *testing.T) { }, // case 3 - tab delimited { - csv: "1 2", + csv: "1\t2", expectedDelimiter: '\t', }, // case 4 - pipe delimited diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index f8b62e898..7ae349908 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -7,7 +7,7 @@ package doctor import ( "context" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/migrations" @@ -121,8 +121,8 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er // find null archived repositories { Name: "Repositories with is_archived IS NULL", - Counter: models.CountNullArchivedRepository, - Fixer: models.FixNullArchivedRepository, + Counter: repo_model.CountNullArchivedRepository, + Fixer: repo_model.FixNullArchivedRepository, FixedMessage: "Fixed", }, // find label comments with empty labels @@ -148,8 +148,8 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er }, { Name: "Action with created_unix set as an empty string", - Counter: models.CountActionCreatedUnixString, - Fixer: models.FixActionCreatedUnixString, + Counter: activities_model.CountActionCreatedUnixString, + Fixer: activities_model.FixActionCreatedUnixString, FixedMessage: "Set to zero", }, } diff --git a/modules/doctor/usertype.go b/modules/doctor/usertype.go index 34e12afe7..166e38bd2 100644 --- a/modules/doctor/usertype.go +++ b/modules/doctor/usertype.go @@ -7,19 +7,19 @@ package doctor import ( "context" - "code.gitea.io/gitea/models" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" ) func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error { - count, err := models.CountWrongUserType() + count, err := user_model.CountWrongUserType() if err != nil { logger.Critical("Error: %v whilst counting wrong user types") return err } if count > 0 { if autofix { - if count, err = models.FixWrongUserType(); err != nil { + if count, err = user_model.FixWrongUserType(); err != nil { logger.Critical("Error: %v whilst fixing wrong user types") return err } diff --git a/modules/emoji/emoji_data.go b/modules/emoji/emoji_data.go index 1fb08767b..1e14d3de6 100644 --- a/modules/emoji/emoji_data.go +++ b/modules/emoji/emoji_data.go @@ -4,9 +4,8 @@ package emoji -// Code generated by gen.go. DO NOT EDIT. +// Code generated by build/generate-emoji.go. DO NOT EDIT. // Sourced from https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json -// var GemojiData = Gemoji{ {"\U0001f44d", "thumbs up", []string{"+1", "thumbsup"}, "6.0", true}, {"\U0001f44e", "thumbs down", []string{"-1", "thumbsdown"}, "6.0", true}, @@ -129,7 +128,7 @@ var GemojiData = Gemoji{ {"\U0001f50b", "battery", []string{"battery"}, "6.0", false}, {"\U0001f3d6\ufe0f", "beach with umbrella", []string{"beach_umbrella"}, "7.0", false}, {"\U0001f43b", "bear", []string{"bear"}, "6.0", false}, - {"\U0001f9d4", "man: beard", []string{"bearded_person"}, "11.0", true}, + {"\U0001f9d4", "person: beard", []string{"bearded_person"}, "11.0", true}, {"\U0001f6cf\ufe0f", "bed", []string{"bed"}, "7.0", false}, {"\U0001f41d", "honeybee", []string{"bee", "honeybee"}, "6.0", false}, {"\U0001f37a", "beer mug", []string{"beer"}, "6.0", false}, @@ -377,14 +376,14 @@ var GemojiData = Gemoji{ {"\U0001f1e8\U0001f1ee", "flag: Cรดte dโ€™Ivoire", []string{"cote_divoire"}, "6.0", false}, {"\U0001f6cb\ufe0f", "couch and lamp", []string{"couch_and_lamp"}, "7.0", false}, {"\U0001f46b", "woman and man holding hands", []string{"couple"}, "6.0", true}, - {"\U0001f491", "couple with heart", []string{"couple_with_heart"}, "6.0", false}, - {"\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man", []string{"couple_with_heart_man_man"}, "6.0", false}, - {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man", []string{"couple_with_heart_woman_man"}, "11.0", false}, - {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman", []string{"couple_with_heart_woman_woman"}, "6.0", false}, - {"\U0001f48f", "kiss", []string{"couplekiss"}, "6.0", false}, - {"\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man", []string{"couplekiss_man_man"}, "6.0", false}, - {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man", []string{"couplekiss_man_woman"}, "11.0", false}, - {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman", []string{"couplekiss_woman_woman"}, "6.0", false}, + {"\U0001f491", "couple with heart", []string{"couple_with_heart"}, "6.0", true}, + {"\U0001f468\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man", []string{"couple_with_heart_man_man"}, "6.0", true}, + {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man", []string{"couple_with_heart_woman_man"}, "11.0", true}, + {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman", []string{"couple_with_heart_woman_woman"}, "6.0", true}, + {"\U0001f48f", "kiss", []string{"couplekiss"}, "6.0", true}, + {"\U0001f468\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man", []string{"couplekiss_man_man"}, "6.0", true}, + {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man", []string{"couplekiss_man_woman"}, "11.0", true}, + {"\U0001f469\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman", []string{"couplekiss_woman_woman"}, "6.0", true}, {"\U0001f42e", "cow face", []string{"cow"}, "6.0", false}, {"\U0001f404", "cow", []string{"cow2"}, "6.0", false}, {"\U0001f920", "cowboy hat face", []string{"cowboy_hat_face"}, "9.0", false}, @@ -429,7 +428,7 @@ var GemojiData = Gemoji{ {"\U0001f46f\u200d\u2640\ufe0f", "women with bunny ears", []string{"dancing_women"}, "11.0", false}, {"\U0001f361", "dango", []string{"dango"}, "6.0", false}, {"\U0001f576\ufe0f", "sunglasses", []string{"dark_sunglasses"}, "7.0", false}, - {"\U0001f3af", "direct hit", []string{"dart"}, "6.0", false}, + {"\U0001f3af", "bullseye", []string{"dart"}, "6.0", false}, {"\U0001f4a8", "dashing away", []string{"dash"}, "6.0", false}, {"\U0001f4c5", "calendar", []string{"date"}, "6.0", false}, {"\U0001f1e9\U0001f1ea", "flag: Germany", []string{"de"}, "6.0", false}, @@ -453,7 +452,7 @@ var GemojiData = Gemoji{ {"\U0001f93f", "diving mask", []string{"diving_mask"}, "12.0", false}, {"\U0001fa94", "diya lamp", []string{"diya_lamp"}, "12.0", false}, {"\U0001f4ab", "dizzy", []string{"dizzy"}, "6.0", false}, - {"\U0001f635", "dizzy face", []string{"dizzy_face"}, "6.0", false}, + {"\U0001f635", "knocked-out face", []string{"dizzy_face"}, "6.0", false}, {"\U0001f1e9\U0001f1ef", "flag: Djibouti", []string{"djibouti"}, "6.0", false}, {"\U0001f9ec", "dna", []string{"dna"}, "11.0", false}, {"\U0001f6af", "no littering", []string{"do_not_litter"}, "6.0", false}, @@ -478,7 +477,6 @@ var GemojiData = Gemoji{ {"\U0001f986", "duck", []string{"duck"}, "9.0", false}, {"\U0001f95f", "dumpling", []string{"dumpling"}, "11.0", false}, {"\U0001f4c0", "dvd", []string{"dvd"}, "6.0", false}, - {"\U0001f4e7", "e-mail", []string{"e-mail"}, "6.0", false}, {"\U0001f985", "eagle", []string{"eagle"}, "9.0", false}, {"\U0001f442", "ear", []string{"ear"}, "6.0", true}, {"\U0001f33e", "sheaf of rice", []string{"ear_of_rice"}, "6.0", false}, @@ -500,9 +498,10 @@ var GemojiData = Gemoji{ {"\U0001f9dd", "elf", []string{"elf"}, "11.0", true}, {"\U0001f9dd\u200d\u2642\ufe0f", "man elf", []string{"elf_man"}, "11.0", true}, {"\U0001f9dd\u200d\u2640\ufe0f", "woman elf", []string{"elf_woman"}, "11.0", true}, - {"\u2709\ufe0f", "envelope", []string{"email", "envelope"}, "", false}, + {"\U0001f4e7", "e-mail", []string{"email", "e-mail"}, "6.0", false}, {"\U0001f51a", "END arrow", []string{"end"}, "6.0", false}, {"\U0001f3f4\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f", "flag: England", []string{"england"}, "11.0", false}, + {"\u2709\ufe0f", "envelope", []string{"envelope"}, "", false}, {"\U0001f4e9", "envelope with arrow", []string{"envelope_with_arrow"}, "6.0", false}, {"\U0001f1ec\U0001f1f6", "flag: Equatorial Guinea", []string{"equatorial_guinea"}, "6.0", false}, {"\U0001f1ea\U0001f1f7", "flag: Eritrea", []string{"eritrea"}, "6.0", false}, @@ -514,7 +513,7 @@ var GemojiData = Gemoji{ {"\U0001f3f0", "castle", []string{"european_castle"}, "6.0", false}, {"\U0001f3e4", "post office", []string{"european_post_office"}, "6.0", false}, {"\U0001f332", "evergreen tree", []string{"evergreen_tree"}, "6.0", false}, - {"\u2757", "exclamation mark", []string{"exclamation", "heavy_exclamation_mark"}, "5.2", false}, + {"\u2757", "red exclamation mark", []string{"exclamation", "heavy_exclamation_mark"}, "5.2", false}, {"\U0001f92f", "exploding head", []string{"exploding_head"}, "11.0", false}, {"\U0001f611", "expressionless face", []string{"expressionless"}, "6.1", false}, {"\U0001f441\ufe0f", "eye", []string{"eye"}, "7.0", false}, @@ -689,7 +688,7 @@ var GemojiData = Gemoji{ {"\U0001f1ec\U0001f1f3", "flag: Guinea", []string{"guinea"}, "6.0", false}, {"\U0001f1ec\U0001f1fc", "flag: Guinea-Bissau", []string{"guinea_bissau"}, "6.0", false}, {"\U0001f3b8", "guitar", []string{"guitar"}, "6.0", false}, - {"\U0001f52b", "pistol", []string{"gun"}, "6.0", false}, + {"\U0001f52b", "water pistol", []string{"gun"}, "6.0", false}, {"\U0001f1ec\U0001f1fe", "flag: Guyana", []string{"guyana"}, "6.0", false}, {"\U0001f487", "person getting haircut", []string{"haircut"}, "6.0", true}, {"\U0001f487\u200d\u2642\ufe0f", "man getting haircut", []string{"haircut_man"}, "6.0", true}, @@ -1228,7 +1227,7 @@ var GemojiData = Gemoji{ {"\U0001f4cc", "pushpin", []string{"pushpin"}, "6.0", false}, {"\U0001f6ae", "litter in bin sign", []string{"put_litter_in_its_place"}, "6.0", false}, {"\U0001f1f6\U0001f1e6", "flag: Qatar", []string{"qatar"}, "6.0", false}, - {"\u2753", "question mark", []string{"question"}, "6.0", false}, + {"\u2753", "red question mark", []string{"question"}, "6.0", false}, {"\U0001f430", "rabbit face", []string{"rabbit"}, "6.0", false}, {"\U0001f407", "rabbit", []string{"rabbit2"}, "6.0", false}, {"\U0001f99d", "raccoon", []string{"raccoon"}, "11.0", false}, @@ -1751,61 +1750,61 @@ var GemojiData = Gemoji{ {"\U0001f44d\U0001f3fc", "thumbs up: Medium-Light Skin Tone", []string{"+1_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44d\U0001f3fd", "thumbs up: Medium Skin Tone", []string{"+1_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f44d\U0001f3fe", "thumbs up: Medium-Dark Skin Tone", []string{"+1_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f44e\U0001f3ff", "thumbs down: Dark Skin Tone", []string{"-1_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f44e\U0001f3fb", "thumbs down: Light Skin Tone", []string{"-1_Light_Skin_Tone"}, "12.0", false}, {"\U0001f44e\U0001f3fc", "thumbs down: Medium-Light Skin Tone", []string{"-1_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44e\U0001f3fd", "thumbs down: Medium Skin Tone", []string{"-1_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f44e\U0001f3fe", "thumbs down: Medium-Dark Skin Tone", []string{"-1_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f44e\U0001f3ff", "thumbs down: Dark Skin Tone", []string{"-1_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc", "person: Medium-Light Skin Tone", []string{"adult_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd", "person: Medium Skin Tone", []string{"adult_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe", "person: Medium-Dark Skin Tone", []string{"adult_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff", "person: Dark Skin Tone", []string{"adult_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb", "person: Light Skin Tone", []string{"adult_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc", "person: Medium-Light Skin Tone", []string{"adult_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f47c\U0001f3fb", "baby angel: Light Skin Tone", []string{"angel_Light_Skin_Tone"}, "12.0", false}, {"\U0001f47c\U0001f3fc", "baby angel: Medium-Light Skin Tone", []string{"angel_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f47c\U0001f3fd", "baby angel: Medium Skin Tone", []string{"angel_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f47c\U0001f3fe", "baby angel: Medium-Dark Skin Tone", []string{"angel_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f47c\U0001f3ff", "baby angel: Dark Skin Tone", []string{"angel_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fe\u200d\U0001f3a8", "artist: Medium-Dark Skin Tone", []string{"artist_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\U0001f3a8", "artist: Dark Skin Tone", []string{"artist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f3a8", "artist: Light Skin Tone", []string{"artist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f3a8", "artist: Medium-Light Skin Tone", []string{"artist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f3a8", "artist: Medium Skin Tone", []string{"artist_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f680", "astronaut: Light Skin Tone", []string{"astronaut_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fe\u200d\U0001f3a8", "artist: Medium-Dark Skin Tone", []string{"artist_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\U0001f3a8", "artist: Dark Skin Tone", []string{"artist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f680", "astronaut: Medium-Light Skin Tone", []string{"astronaut_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f680", "astronaut: Medium Skin Tone", []string{"astronaut_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f680", "astronaut: Medium-Dark Skin Tone", []string{"astronaut_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f680", "astronaut: Dark Skin Tone", []string{"astronaut_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f680", "astronaut: Light Skin Tone", []string{"astronaut_Light_Skin_Tone"}, "12.0", false}, {"\U0001f476\U0001f3fb", "baby: Light Skin Tone", []string{"baby_Light_Skin_Tone"}, "12.0", false}, {"\U0001f476\U0001f3fc", "baby: Medium-Light Skin Tone", []string{"baby_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f476\U0001f3fd", "baby: Medium Skin Tone", []string{"baby_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f476\U0001f3fe", "baby: Medium-Dark Skin Tone", []string{"baby_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f476\U0001f3ff", "baby: Dark Skin Tone", []string{"baby_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f9b2", "man: bald: Medium-Dark Skin Tone", []string{"bald_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f9b2", "man: bald: Dark Skin Tone", []string{"bald_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f9b2", "man: bald: Light Skin Tone", []string{"bald_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f9b2", "man: bald: Medium-Light Skin Tone", []string{"bald_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9b2", "man: bald: Medium Skin Tone", []string{"bald_man_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f9b2", "man: bald: Medium-Dark Skin Tone", []string{"bald_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f9b2", "man: bald: Dark Skin Tone", []string{"bald_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f9b2", "woman: bald: Dark Skin Tone", []string{"bald_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\U0001f9b2", "woman: bald: Light Skin Tone", []string{"bald_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9b2", "woman: bald: Medium-Light Skin Tone", []string{"bald_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9b2", "woman: bald: Medium Skin Tone", []string{"bald_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f9b2", "woman: bald: Medium-Dark Skin Tone", []string{"bald_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f9b2", "woman: bald: Dark Skin Tone", []string{"bald_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\U0001f9b2", "woman: bald: Light Skin Tone", []string{"bald_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f6c0\U0001f3fe", "person taking bath: Medium-Dark Skin Tone", []string{"bath_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6c0\U0001f3ff", "person taking bath: Dark Skin Tone", []string{"bath_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6c0\U0001f3fb", "person taking bath: Light Skin Tone", []string{"bath_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6c0\U0001f3fc", "person taking bath: Medium-Light Skin Tone", []string{"bath_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6c0\U0001f3fd", "person taking bath: Medium Skin Tone", []string{"bath_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f6c0\U0001f3fe", "person taking bath: Medium-Dark Skin Tone", []string{"bath_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6c0\U0001f3ff", "person taking bath: Dark Skin Tone", []string{"bath_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d4\U0001f3fb", "man: beard: Light Skin Tone", []string{"bearded_person_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d4\U0001f3fc", "man: beard: Medium-Light Skin Tone", []string{"bearded_person_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d4\U0001f3fd", "man: beard: Medium Skin Tone", []string{"bearded_person_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d4\U0001f3fe", "man: beard: Medium-Dark Skin Tone", []string{"bearded_person_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d4\U0001f3ff", "man: beard: Dark Skin Tone", []string{"bearded_person_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d4\U0001f3fd", "person: beard: Medium Skin Tone", []string{"bearded_person_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d4\U0001f3fe", "person: beard: Medium-Dark Skin Tone", []string{"bearded_person_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d4\U0001f3ff", "person: beard: Dark Skin Tone", []string{"bearded_person_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d4\U0001f3fb", "person: beard: Light Skin Tone", []string{"bearded_person_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d4\U0001f3fc", "person: beard: Medium-Light Skin Tone", []string{"bearded_person_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f6b4\U0001f3fd", "person biking: Medium Skin Tone", []string{"bicyclist_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f6b4\U0001f3fe", "person biking: Medium-Dark Skin Tone", []string{"bicyclist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3ff", "person biking: Dark Skin Tone", []string{"bicyclist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3fb", "person biking: Light Skin Tone", []string{"bicyclist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3fc", "person biking: Medium-Light Skin Tone", []string{"bicyclist_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f6b4\U0001f3fd", "person biking: Medium Skin Tone", []string{"bicyclist_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f6b4\U0001f3fe", "person biking: Medium-Dark Skin Tone", []string{"bicyclist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3fe\u200d\u2642\ufe0f", "man biking: Medium-Dark Skin Tone", []string{"biking_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3ff\u200d\u2642\ufe0f", "man biking: Dark Skin Tone", []string{"biking_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b4\U0001f3fb\u200d\u2642\ufe0f", "man biking: Light Skin Tone", []string{"biking_man_Light_Skin_Tone"}, "12.0", false}, @@ -1821,21 +1820,21 @@ var GemojiData = Gemoji{ {"\U0001f471\U0001f3fd\u200d\u2642\ufe0f", "man: blond hair: Medium Skin Tone", []string{"blond_haired_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fe\u200d\u2642\ufe0f", "man: blond hair: Medium-Dark Skin Tone", []string{"blond_haired_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3ff\u200d\u2642\ufe0f", "man: blond hair: Dark Skin Tone", []string{"blond_haired_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f471\U0001f3fb", "person: blond hair: Light Skin Tone", []string{"blond_haired_person_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f471\U0001f3fc", "person: blond hair: Medium-Light Skin Tone", []string{"blond_haired_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fd", "person: blond hair: Medium Skin Tone", []string{"blond_haired_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fe", "person: blond hair: Medium-Dark Skin Tone", []string{"blond_haired_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3ff", "person: blond hair: Dark Skin Tone", []string{"blond_haired_person_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f471\U0001f3fb", "person: blond hair: Light Skin Tone", []string{"blond_haired_person_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f471\U0001f3fc", "person: blond hair: Medium-Light Skin Tone", []string{"blond_haired_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fb\u200d\u2640\ufe0f", "woman: blond hair: Light Skin Tone", []string{"blond_haired_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fc\u200d\u2640\ufe0f", "woman: blond hair: Medium-Light Skin Tone", []string{"blond_haired_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fd\u200d\u2640\ufe0f", "woman: blond hair: Medium Skin Tone", []string{"blond_haired_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3fe\u200d\u2640\ufe0f", "woman: blond hair: Medium-Dark Skin Tone", []string{"blond_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f471\U0001f3ff\u200d\u2640\ufe0f", "woman: blond hair: Dark Skin Tone", []string{"blond_haired_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\u26f9\U0001f3fe\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Medium-Dark Skin Tone", []string{"bouncing_ball_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\u26f9\U0001f3ff\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Dark Skin Tone", []string{"bouncing_ball_man_Dark_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fb\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Light Skin Tone", []string{"bouncing_ball_man_Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fc\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Medium-Light Skin Tone", []string{"bouncing_ball_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fd\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Medium Skin Tone", []string{"bouncing_ball_man_Medium_Skin_Tone"}, "12.0", false}, + {"\u26f9\U0001f3fe\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Medium-Dark Skin Tone", []string{"bouncing_ball_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\u26f9\U0001f3ff\ufe0f\u200d\u2642\ufe0f", "man bouncing ball: Dark Skin Tone", []string{"bouncing_ball_man_Dark_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fb\ufe0f", "person bouncing ball: Light Skin Tone", []string{"bouncing_ball_person_Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fc\ufe0f", "person bouncing ball: Medium-Light Skin Tone", []string{"bouncing_ball_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fd\ufe0f", "person bouncing ball: Medium Skin Tone", []string{"bouncing_ball_person_Medium_Skin_Tone"}, "12.0", false}, @@ -1846,31 +1845,31 @@ var GemojiData = Gemoji{ {"\u26f9\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman bouncing ball: Light Skin Tone", []string{"bouncing_ball_woman_Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fc\ufe0f\u200d\u2640\ufe0f", "woman bouncing ball: Medium-Light Skin Tone", []string{"bouncing_ball_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u26f9\U0001f3fd\ufe0f\u200d\u2640\ufe0f", "woman bouncing ball: Medium Skin Tone", []string{"bouncing_ball_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f647\U0001f3fb", "person bowing: Light Skin Tone", []string{"bow_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f647\U0001f3fc", "person bowing: Medium-Light Skin Tone", []string{"bow_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fd", "person bowing: Medium Skin Tone", []string{"bow_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fe", "person bowing: Medium-Dark Skin Tone", []string{"bow_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3ff", "person bowing: Dark Skin Tone", []string{"bow_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f647\U0001f3fb", "person bowing: Light Skin Tone", []string{"bow_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f647\U0001f3fc", "person bowing: Medium-Light Skin Tone", []string{"bow_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3ff\u200d\u2642\ufe0f", "man bowing: Dark Skin Tone", []string{"bowing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fb\u200d\u2642\ufe0f", "man bowing: Light Skin Tone", []string{"bowing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fc\u200d\u2642\ufe0f", "man bowing: Medium-Light Skin Tone", []string{"bowing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fd\u200d\u2642\ufe0f", "man bowing: Medium Skin Tone", []string{"bowing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fe\u200d\u2642\ufe0f", "man bowing: Medium-Dark Skin Tone", []string{"bowing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f647\U0001f3fe\u200d\u2640\ufe0f", "woman bowing: Medium-Dark Skin Tone", []string{"bowing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f647\U0001f3ff\u200d\u2640\ufe0f", "woman bowing: Dark Skin Tone", []string{"bowing_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fb\u200d\u2640\ufe0f", "woman bowing: Light Skin Tone", []string{"bowing_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fc\u200d\u2640\ufe0f", "woman bowing: Medium-Light Skin Tone", []string{"bowing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f647\U0001f3fd\u200d\u2640\ufe0f", "woman bowing: Medium Skin Tone", []string{"bowing_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f647\U0001f3fe\u200d\u2640\ufe0f", "woman bowing: Medium-Dark Skin Tone", []string{"bowing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f647\U0001f3ff\u200d\u2640\ufe0f", "woman bowing: Dark Skin Tone", []string{"bowing_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f466\U0001f3fb", "boy: Light Skin Tone", []string{"boy_Light_Skin_Tone"}, "12.0", false}, {"\U0001f466\U0001f3fc", "boy: Medium-Light Skin Tone", []string{"boy_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f466\U0001f3fd", "boy: Medium Skin Tone", []string{"boy_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f466\U0001f3fe", "boy: Medium-Dark Skin Tone", []string{"boy_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f466\U0001f3ff", "boy: Dark Skin Tone", []string{"boy_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f931\U0001f3fe", "breast-feeding: Medium-Dark Skin Tone", []string{"breast_feeding_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f931\U0001f3ff", "breast-feeding: Dark Skin Tone", []string{"breast_feeding_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f931\U0001f3fb", "breast-feeding: Light Skin Tone", []string{"breast_feeding_Light_Skin_Tone"}, "12.0", false}, {"\U0001f931\U0001f3fc", "breast-feeding: Medium-Light Skin Tone", []string{"breast_feeding_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f931\U0001f3fd", "breast-feeding: Medium Skin Tone", []string{"breast_feeding_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f931\U0001f3fe", "breast-feeding: Medium-Dark Skin Tone", []string{"breast_feeding_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f931\U0001f3ff", "breast-feeding: Dark Skin Tone", []string{"breast_feeding_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f574\U0001f3fb\ufe0f", "person in suit levitating: Light Skin Tone", []string{"business_suit_levitating_Light_Skin_Tone"}, "12.0", false}, {"\U0001f574\U0001f3fc\ufe0f", "person in suit levitating: Medium-Light Skin Tone", []string{"business_suit_levitating_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f574\U0001f3fd\ufe0f", "person in suit levitating: Medium Skin Tone", []string{"business_suit_levitating_Medium_Skin_Tone"}, "12.0", false}, @@ -1881,116 +1880,156 @@ var GemojiData = Gemoji{ {"\U0001f919\U0001f3fd", "call me hand: Medium Skin Tone", []string{"call_me_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f919\U0001f3fe", "call me hand: Medium-Dark Skin Tone", []string{"call_me_hand_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f919\U0001f3ff", "call me hand: Dark Skin Tone", []string{"call_me_hand_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f938\U0001f3ff", "person cartwheeling: Dark Skin Tone", []string{"cartwheeling_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f938\U0001f3fb", "person cartwheeling: Light Skin Tone", []string{"cartwheeling_Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fc", "person cartwheeling: Medium-Light Skin Tone", []string{"cartwheeling_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fd", "person cartwheeling: Medium Skin Tone", []string{"cartwheeling_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fe", "person cartwheeling: Medium-Dark Skin Tone", []string{"cartwheeling_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f938\U0001f3ff", "person cartwheeling: Dark Skin Tone", []string{"cartwheeling_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f938\U0001f3fb", "person cartwheeling: Light Skin Tone", []string{"cartwheeling_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d2\U0001f3fb", "child: Light Skin Tone", []string{"child_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d2\U0001f3fc", "child: Medium-Light Skin Tone", []string{"child_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d2\U0001f3fd", "child: Medium Skin Tone", []string{"child_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d2\U0001f3fe", "child: Medium-Dark Skin Tone", []string{"child_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d2\U0001f3ff", "child: Dark Skin Tone", []string{"child_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d2\U0001f3fb", "child: Light Skin Tone", []string{"child_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d2\U0001f3fc", "child: Medium-Light Skin Tone", []string{"child_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f44f\U0001f3fb", "clapping hands: Light Skin Tone", []string{"clap_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f44f\U0001f3fc", "clapping hands: Medium-Light Skin Tone", []string{"clap_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44f\U0001f3fd", "clapping hands: Medium Skin Tone", []string{"clap_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f44f\U0001f3fe", "clapping hands: Medium-Dark Skin Tone", []string{"clap_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f44f\U0001f3ff", "clapping hands: Dark Skin Tone", []string{"clap_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f44f\U0001f3fb", "clapping hands: Light Skin Tone", []string{"clap_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f44f\U0001f3fc", "clapping hands: Medium-Light Skin Tone", []string{"clap_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d7\U0001f3fb", "person climbing: Light Skin Tone", []string{"climbing_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d7\U0001f3fc", "person climbing: Medium-Light Skin Tone", []string{"climbing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fd", "person climbing: Medium Skin Tone", []string{"climbing_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fe", "person climbing: Medium-Dark Skin Tone", []string{"climbing_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3ff", "person climbing: Dark Skin Tone", []string{"climbing_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d7\U0001f3fb", "person climbing: Light Skin Tone", []string{"climbing_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d7\U0001f3fc", "person climbing: Medium-Light Skin Tone", []string{"climbing_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d7\U0001f3ff\u200d\u2642\ufe0f", "man climbing: Dark Skin Tone", []string{"climbing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fb\u200d\u2642\ufe0f", "man climbing: Light Skin Tone", []string{"climbing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fc\u200d\u2642\ufe0f", "man climbing: Medium-Light Skin Tone", []string{"climbing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fd\u200d\u2642\ufe0f", "man climbing: Medium Skin Tone", []string{"climbing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fe\u200d\u2642\ufe0f", "man climbing: Medium-Dark Skin Tone", []string{"climbing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d7\U0001f3ff\u200d\u2642\ufe0f", "man climbing: Dark Skin Tone", []string{"climbing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fb\u200d\u2640\ufe0f", "woman climbing: Light Skin Tone", []string{"climbing_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fc\u200d\u2640\ufe0f", "woman climbing: Medium-Light Skin Tone", []string{"climbing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fd\u200d\u2640\ufe0f", "woman climbing: Medium Skin Tone", []string{"climbing_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3fe\u200d\u2640\ufe0f", "woman climbing: Medium-Dark Skin Tone", []string{"climbing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d7\U0001f3ff\u200d\u2640\ufe0f", "woman climbing: Dark Skin Tone", []string{"climbing_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f477\U0001f3fb", "construction worker: Light Skin Tone", []string{"construction_worker_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f477\U0001f3fc", "construction worker: Medium-Light Skin Tone", []string{"construction_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fd", "construction worker: Medium Skin Tone", []string{"construction_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fe", "construction worker: Medium-Dark Skin Tone", []string{"construction_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3ff", "construction worker: Dark Skin Tone", []string{"construction_worker_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f477\U0001f3fb", "construction worker: Light Skin Tone", []string{"construction_worker_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f477\U0001f3fc", "construction worker: Medium-Light Skin Tone", []string{"construction_worker_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f477\U0001f3ff\u200d\u2642\ufe0f", "man construction worker: Dark Skin Tone", []string{"construction_worker_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fb\u200d\u2642\ufe0f", "man construction worker: Light Skin Tone", []string{"construction_worker_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fc\u200d\u2642\ufe0f", "man construction worker: Medium-Light Skin Tone", []string{"construction_worker_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fd\u200d\u2642\ufe0f", "man construction worker: Medium Skin Tone", []string{"construction_worker_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fe\u200d\u2642\ufe0f", "man construction worker: Medium-Dark Skin Tone", []string{"construction_worker_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f477\U0001f3ff\u200d\u2642\ufe0f", "man construction worker: Dark Skin Tone", []string{"construction_worker_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f477\U0001f3ff\u200d\u2640\ufe0f", "woman construction worker: Dark Skin Tone", []string{"construction_worker_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fb\u200d\u2640\ufe0f", "woman construction worker: Light Skin Tone", []string{"construction_worker_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fc\u200d\u2640\ufe0f", "woman construction worker: Medium-Light Skin Tone", []string{"construction_worker_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fd\u200d\u2640\ufe0f", "woman construction worker: Medium Skin Tone", []string{"construction_worker_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f477\U0001f3fe\u200d\u2640\ufe0f", "woman construction worker: Medium-Dark Skin Tone", []string{"construction_worker_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f477\U0001f3ff\u200d\u2640\ufe0f", "woman construction worker: Dark Skin Tone", []string{"construction_worker_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f373", "cook: Light Skin Tone", []string{"cook_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f373", "cook: Medium-Light Skin Tone", []string{"cook_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f373", "cook: Medium Skin Tone", []string{"cook_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f373", "cook: Medium-Dark Skin Tone", []string{"cook_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f373", "cook: Dark Skin Tone", []string{"cook_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f373", "cook: Light Skin Tone", []string{"cook_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f373", "cook: Medium-Light Skin Tone", []string{"cook_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46b\U0001f3fb", "woman and man holding hands: Light Skin Tone", []string{"couple_Light_Skin_Tone"}, "12.0", false}, {"\U0001f46b\U0001f3fc", "woman and man holding hands: Medium-Light Skin Tone", []string{"couple_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46b\U0001f3fd", "woman and man holding hands: Medium Skin Tone", []string{"couple_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f46b\U0001f3fe", "woman and man holding hands: Medium-Dark Skin Tone", []string{"couple_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f46b\U0001f3ff", "woman and man holding hands: Dark Skin Tone", []string{"couple_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f491\U0001f3fd", "couple with heart: Medium Skin Tone", []string{"couple_with_heart_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f491\U0001f3fe", "couple with heart: Medium-Dark Skin Tone", []string{"couple_with_heart_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f491\U0001f3ff", "couple with heart: Dark Skin Tone", []string{"couple_with_heart_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f491\U0001f3fb", "couple with heart: Light Skin Tone", []string{"couple_with_heart_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f491\U0001f3fc", "couple with heart: Medium-Light Skin Tone", []string{"couple_with_heart_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man: Medium Skin Tone", []string{"couple_with_heart_man_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man: Medium-Dark Skin Tone", []string{"couple_with_heart_man_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man: Dark Skin Tone", []string{"couple_with_heart_man_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man: Light Skin Tone", []string{"couple_with_heart_man_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: man, man: Medium-Light Skin Tone", []string{"couple_with_heart_man_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man: Light Skin Tone", []string{"couple_with_heart_woman_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man: Medium-Light Skin Tone", []string{"couple_with_heart_woman_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man: Medium Skin Tone", []string{"couple_with_heart_woman_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man: Medium-Dark Skin Tone", []string{"couple_with_heart_woman_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f468", "couple with heart: woman, man: Dark Skin Tone", []string{"couple_with_heart_woman_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman: Medium Skin Tone", []string{"couple_with_heart_woman_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman: Medium-Dark Skin Tone", []string{"couple_with_heart_woman_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman: Dark Skin Tone", []string{"couple_with_heart_woman_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman: Light Skin Tone", []string{"couple_with_heart_woman_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f469", "couple with heart: woman, woman: Medium-Light Skin Tone", []string{"couple_with_heart_woman_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f48f\U0001f3fe", "kiss: Medium-Dark Skin Tone", []string{"couplekiss_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f48f\U0001f3ff", "kiss: Dark Skin Tone", []string{"couplekiss_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f48f\U0001f3fb", "kiss: Light Skin Tone", []string{"couplekiss_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f48f\U0001f3fc", "kiss: Medium-Light Skin Tone", []string{"couplekiss_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f48f\U0001f3fd", "kiss: Medium Skin Tone", []string{"couplekiss_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man: Dark Skin Tone", []string{"couplekiss_man_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man: Light Skin Tone", []string{"couplekiss_man_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man: Medium-Light Skin Tone", []string{"couplekiss_man_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man: Medium Skin Tone", []string{"couplekiss_man_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: man, man: Medium-Dark Skin Tone", []string{"couplekiss_man_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man: Light Skin Tone", []string{"couplekiss_man_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man: Medium-Light Skin Tone", []string{"couplekiss_man_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man: Medium Skin Tone", []string{"couplekiss_man_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man: Medium-Dark Skin Tone", []string{"couplekiss_man_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f468", "kiss: woman, man: Dark Skin Tone", []string{"couplekiss_man_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman: Light Skin Tone", []string{"couplekiss_woman_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fc\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman: Medium-Light Skin Tone", []string{"couplekiss_woman_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman: Medium Skin Tone", []string{"couplekiss_woman_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman: Medium-Dark Skin Tone", []string{"couplekiss_woman_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\u2764\ufe0f\u200d\U0001f48b\u200d\U0001f469", "kiss: woman, woman: Dark Skin Tone", []string{"couplekiss_woman_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f91e\U0001f3fe", "crossed fingers: Medium-Dark Skin Tone", []string{"crossed_fingers_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f91e\U0001f3ff", "crossed fingers: Dark Skin Tone", []string{"crossed_fingers_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f91e\U0001f3fb", "crossed fingers: Light Skin Tone", []string{"crossed_fingers_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91e\U0001f3fc", "crossed fingers: Medium-Light Skin Tone", []string{"crossed_fingers_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f91e\U0001f3fd", "crossed fingers: Medium Skin Tone", []string{"crossed_fingers_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f91e\U0001f3fe", "crossed fingers: Medium-Dark Skin Tone", []string{"crossed_fingers_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fd\u200d\U0001f9b1", "man: curly hair: Medium Skin Tone", []string{"curly_haired_man_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f9b1", "man: curly hair: Medium-Dark Skin Tone", []string{"curly_haired_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f9b1", "man: curly hair: Dark Skin Tone", []string{"curly_haired_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f9b1", "man: curly hair: Light Skin Tone", []string{"curly_haired_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f9b1", "man: curly hair: Medium-Light Skin Tone", []string{"curly_haired_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fd\u200d\U0001f9b1", "man: curly hair: Medium Skin Tone", []string{"curly_haired_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f9b1", "man: curly hair: Medium-Dark Skin Tone", []string{"curly_haired_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f9b1", "woman: curly hair: Dark Skin Tone", []string{"curly_haired_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9b1", "woman: curly hair: Light Skin Tone", []string{"curly_haired_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9b1", "woman: curly hair: Medium-Light Skin Tone", []string{"curly_haired_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9b1", "woman: curly hair: Medium Skin Tone", []string{"curly_haired_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f9b1", "woman: curly hair: Medium-Dark Skin Tone", []string{"curly_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f9b1", "woman: curly hair: Dark Skin Tone", []string{"curly_haired_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9cf\U0001f3ff\u200d\u2642\ufe0f", "deaf man: Dark Skin Tone", []string{"deaf_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fb\u200d\u2642\ufe0f", "deaf man: Light Skin Tone", []string{"deaf_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fc\u200d\u2642\ufe0f", "deaf man: Medium-Light Skin Tone", []string{"deaf_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fd\u200d\u2642\ufe0f", "deaf man: Medium Skin Tone", []string{"deaf_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fe\u200d\u2642\ufe0f", "deaf man: Medium-Dark Skin Tone", []string{"deaf_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cf\U0001f3ff\u200d\u2642\ufe0f", "deaf man: Dark Skin Tone", []string{"deaf_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9cf\U0001f3fb", "deaf person: Light Skin Tone", []string{"deaf_person_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9cf\U0001f3fc", "deaf person: Medium-Light Skin Tone", []string{"deaf_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fd", "deaf person: Medium Skin Tone", []string{"deaf_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fe", "deaf person: Medium-Dark Skin Tone", []string{"deaf_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3ff", "deaf person: Dark Skin Tone", []string{"deaf_person_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cf\U0001f3fb", "deaf person: Light Skin Tone", []string{"deaf_person_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9cf\U0001f3fc", "deaf person: Medium-Light Skin Tone", []string{"deaf_person_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9cf\U0001f3fe\u200d\u2640\ufe0f", "deaf woman: Medium-Dark Skin Tone", []string{"deaf_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9cf\U0001f3ff\u200d\u2640\ufe0f", "deaf woman: Dark Skin Tone", []string{"deaf_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fb\u200d\u2640\ufe0f", "deaf woman: Light Skin Tone", []string{"deaf_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fc\u200d\u2640\ufe0f", "deaf woman: Medium-Light Skin Tone", []string{"deaf_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cf\U0001f3fd\u200d\u2640\ufe0f", "deaf woman: Medium Skin Tone", []string{"deaf_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9cf\U0001f3fe\u200d\u2640\ufe0f", "deaf woman: Medium-Dark Skin Tone", []string{"deaf_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cf\U0001f3ff\u200d\u2640\ufe0f", "deaf woman: Dark Skin Tone", []string{"deaf_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f575\U0001f3fe\ufe0f", "detective: Medium-Dark Skin Tone", []string{"detective_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f575\U0001f3ff\ufe0f", "detective: Dark Skin Tone", []string{"detective_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fb\ufe0f", "detective: Light Skin Tone", []string{"detective_Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fc\ufe0f", "detective: Medium-Light Skin Tone", []string{"detective_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fd\ufe0f", "detective: Medium Skin Tone", []string{"detective_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f442\U0001f3fc", "ear: Medium-Light Skin Tone", []string{"ear_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f442\U0001f3fd", "ear: Medium Skin Tone", []string{"ear_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f575\U0001f3fe\ufe0f", "detective: Medium-Dark Skin Tone", []string{"detective_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f575\U0001f3ff\ufe0f", "detective: Dark Skin Tone", []string{"detective_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f442\U0001f3fe", "ear: Medium-Dark Skin Tone", []string{"ear_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f442\U0001f3ff", "ear: Dark Skin Tone", []string{"ear_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f442\U0001f3fb", "ear: Light Skin Tone", []string{"ear_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f442\U0001f3fc", "ear: Medium-Light Skin Tone", []string{"ear_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f442\U0001f3fd", "ear: Medium Skin Tone", []string{"ear_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9bb\U0001f3fe", "ear with hearing aid: Medium-Dark Skin Tone", []string{"ear_with_hearing_aid_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9bb\U0001f3ff", "ear with hearing aid: Dark Skin Tone", []string{"ear_with_hearing_aid_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9bb\U0001f3fb", "ear with hearing aid: Light Skin Tone", []string{"ear_with_hearing_aid_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9bb\U0001f3fc", "ear with hearing aid: Medium-Light Skin Tone", []string{"ear_with_hearing_aid_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9bb\U0001f3fd", "ear with hearing aid: Medium Skin Tone", []string{"ear_with_hearing_aid_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9bb\U0001f3fe", "ear with hearing aid: Medium-Dark Skin Tone", []string{"ear_with_hearing_aid_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9bb\U0001f3ff", "ear with hearing aid: Dark Skin Tone", []string{"ear_with_hearing_aid_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fb", "elf: Light Skin Tone", []string{"elf_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fc", "elf: Medium-Light Skin Tone", []string{"elf_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fd", "elf: Medium Skin Tone", []string{"elf_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fe", "elf: Medium-Dark Skin Tone", []string{"elf_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3ff", "elf: Dark Skin Tone", []string{"elf_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9dd\U0001f3ff\u200d\u2642\ufe0f", "man elf: Dark Skin Tone", []string{"elf_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fb\u200d\u2642\ufe0f", "man elf: Light Skin Tone", []string{"elf_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fc\u200d\u2642\ufe0f", "man elf: Medium-Light Skin Tone", []string{"elf_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fd\u200d\u2642\ufe0f", "man elf: Medium Skin Tone", []string{"elf_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fe\u200d\u2642\ufe0f", "man elf: Medium-Dark Skin Tone", []string{"elf_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9dd\U0001f3ff\u200d\u2642\ufe0f", "man elf: Dark Skin Tone", []string{"elf_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fb\u200d\u2640\ufe0f", "woman elf: Light Skin Tone", []string{"elf_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fc\u200d\u2640\ufe0f", "woman elf: Medium-Light Skin Tone", []string{"elf_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dd\U0001f3fd\u200d\u2640\ufe0f", "woman elf: Medium Skin Tone", []string{"elf_woman_Medium_Skin_Tone"}, "12.0", false}, @@ -2001,111 +2040,111 @@ var GemojiData = Gemoji{ {"\U0001f926\U0001f3fd", "person facepalming: Medium Skin Tone", []string{"facepalm_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fe", "person facepalming: Medium-Dark Skin Tone", []string{"facepalm_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3ff", "person facepalming: Dark Skin Tone", []string{"facepalm_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\U0001f3ed", "factory worker: Dark Skin Tone", []string{"factory_worker_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f3ed", "factory worker: Light Skin Tone", []string{"factory_worker_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f3ed", "factory worker: Medium-Light Skin Tone", []string{"factory_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f3ed", "factory worker: Medium Skin Tone", []string{"factory_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f3ed", "factory worker: Medium-Dark Skin Tone", []string{"factory_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\U0001f3ed", "factory worker: Dark Skin Tone", []string{"factory_worker_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9da\U0001f3fe", "fairy: Medium-Dark Skin Tone", []string{"fairy_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9da\U0001f3ff", "fairy: Dark Skin Tone", []string{"fairy_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fb", "fairy: Light Skin Tone", []string{"fairy_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fc", "fairy: Medium-Light Skin Tone", []string{"fairy_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fd", "fairy: Medium Skin Tone", []string{"fairy_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9da\U0001f3fe", "fairy: Medium-Dark Skin Tone", []string{"fairy_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9da\U0001f3ff", "fairy: Dark Skin Tone", []string{"fairy_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fb\u200d\u2642\ufe0f", "man fairy: Light Skin Tone", []string{"fairy_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fc\u200d\u2642\ufe0f", "man fairy: Medium-Light Skin Tone", []string{"fairy_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fd\u200d\u2642\ufe0f", "man fairy: Medium Skin Tone", []string{"fairy_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fe\u200d\u2642\ufe0f", "man fairy: Medium-Dark Skin Tone", []string{"fairy_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3ff\u200d\u2642\ufe0f", "man fairy: Dark Skin Tone", []string{"fairy_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9da\U0001f3fe\u200d\u2640\ufe0f", "woman fairy: Medium-Dark Skin Tone", []string{"fairy_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3ff\u200d\u2640\ufe0f", "woman fairy: Dark Skin Tone", []string{"fairy_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fb\u200d\u2640\ufe0f", "woman fairy: Light Skin Tone", []string{"fairy_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fc\u200d\u2640\ufe0f", "woman fairy: Medium-Light Skin Tone", []string{"fairy_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9da\U0001f3fd\u200d\u2640\ufe0f", "woman fairy: Medium Skin Tone", []string{"fairy_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f33e", "farmer: Light Skin Tone", []string{"farmer_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f33e", "farmer: Medium-Light Skin Tone", []string{"farmer_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9da\U0001f3fe\u200d\u2640\ufe0f", "woman fairy: Medium-Dark Skin Tone", []string{"fairy_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f33e", "farmer: Medium Skin Tone", []string{"farmer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f33e", "farmer: Medium-Dark Skin Tone", []string{"farmer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f33e", "farmer: Dark Skin Tone", []string{"farmer_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f33e", "farmer: Light Skin Tone", []string{"farmer_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f33e", "farmer: Medium-Light Skin Tone", []string{"farmer_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f575\U0001f3ff\ufe0f\u200d\u2640\ufe0f", "woman detective: Dark Skin Tone", []string{"female_detective_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f575\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman detective: Light Skin Tone", []string{"female_detective_Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fc\ufe0f\u200d\u2640\ufe0f", "woman detective: Medium-Light Skin Tone", []string{"female_detective_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fd\ufe0f\u200d\u2640\ufe0f", "woman detective: Medium Skin Tone", []string{"female_detective_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fe\ufe0f\u200d\u2640\ufe0f", "woman detective: Medium-Dark Skin Tone", []string{"female_detective_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f575\U0001f3ff\ufe0f\u200d\u2640\ufe0f", "woman detective: Dark Skin Tone", []string{"female_detective_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f575\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman detective: Light Skin Tone", []string{"female_detective_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f692", "firefighter: Medium-Light Skin Tone", []string{"firefighter_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f692", "firefighter: Medium Skin Tone", []string{"firefighter_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f692", "firefighter: Medium-Dark Skin Tone", []string{"firefighter_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f692", "firefighter: Dark Skin Tone", []string{"firefighter_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f692", "firefighter: Light Skin Tone", []string{"firefighter_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f91b\U0001f3fb", "left-facing fist: Light Skin Tone", []string{"fist_left_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91b\U0001f3fc", "left-facing fist: Medium-Light Skin Tone", []string{"fist_left_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f91b\U0001f3fd", "left-facing fist: Medium Skin Tone", []string{"fist_left_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f91b\U0001f3fe", "left-facing fist: Medium-Dark Skin Tone", []string{"fist_left_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f91b\U0001f3ff", "left-facing fist: Dark Skin Tone", []string{"fist_left_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f91b\U0001f3fb", "left-facing fist: Light Skin Tone", []string{"fist_left_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f44a\U0001f3fb", "oncoming fist: Light Skin Tone", []string{"fist_oncoming_Light_Skin_Tone"}, "12.0", false}, {"\U0001f44a\U0001f3fc", "oncoming fist: Medium-Light Skin Tone", []string{"fist_oncoming_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44a\U0001f3fd", "oncoming fist: Medium Skin Tone", []string{"fist_oncoming_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f44a\U0001f3fe", "oncoming fist: Medium-Dark Skin Tone", []string{"fist_oncoming_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f44a\U0001f3ff", "oncoming fist: Dark Skin Tone", []string{"fist_oncoming_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f44a\U0001f3fb", "oncoming fist: Light Skin Tone", []string{"fist_oncoming_Light_Skin_Tone"}, "12.0", false}, + {"\u270a\U0001f3fb", "raised fist: Light Skin Tone", []string{"fist_raised_Light_Skin_Tone"}, "12.0", false}, {"\u270a\U0001f3fc", "raised fist: Medium-Light Skin Tone", []string{"fist_raised_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u270a\U0001f3fd", "raised fist: Medium Skin Tone", []string{"fist_raised_Medium_Skin_Tone"}, "12.0", false}, {"\u270a\U0001f3fe", "raised fist: Medium-Dark Skin Tone", []string{"fist_raised_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\u270a\U0001f3ff", "raised fist: Dark Skin Tone", []string{"fist_raised_Dark_Skin_Tone"}, "12.0", false}, - {"\u270a\U0001f3fb", "raised fist: Light Skin Tone", []string{"fist_raised_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91c\U0001f3fb", "right-facing fist: Light Skin Tone", []string{"fist_right_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91c\U0001f3fc", "right-facing fist: Medium-Light Skin Tone", []string{"fist_right_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f91c\U0001f3fd", "right-facing fist: Medium Skin Tone", []string{"fist_right_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f91c\U0001f3fe", "right-facing fist: Medium-Dark Skin Tone", []string{"fist_right_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f91c\U0001f3ff", "right-facing fist: Dark Skin Tone", []string{"fist_right_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9b6\U0001f3fc", "foot: Medium-Light Skin Tone", []string{"foot_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b6\U0001f3fd", "foot: Medium Skin Tone", []string{"foot_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b6\U0001f3fe", "foot: Medium-Dark Skin Tone", []string{"foot_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b6\U0001f3ff", "foot: Dark Skin Tone", []string{"foot_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b6\U0001f3fb", "foot: Light Skin Tone", []string{"foot_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9b6\U0001f3fc", "foot: Medium-Light Skin Tone", []string{"foot_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64d\U0001f3fd\u200d\u2642\ufe0f", "man frowning: Medium Skin Tone", []string{"frowning_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fe\u200d\u2642\ufe0f", "man frowning: Medium-Dark Skin Tone", []string{"frowning_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3ff\u200d\u2642\ufe0f", "man frowning: Dark Skin Tone", []string{"frowning_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fb\u200d\u2642\ufe0f", "man frowning: Light Skin Tone", []string{"frowning_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fc\u200d\u2642\ufe0f", "man frowning: Medium-Light Skin Tone", []string{"frowning_man_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f64d\U0001f3fd\u200d\u2642\ufe0f", "man frowning: Medium Skin Tone", []string{"frowning_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f64d\U0001f3fb", "person frowning: Light Skin Tone", []string{"frowning_person_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64d\U0001f3fc", "person frowning: Medium-Light Skin Tone", []string{"frowning_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fd", "person frowning: Medium Skin Tone", []string{"frowning_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fe", "person frowning: Medium-Dark Skin Tone", []string{"frowning_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3ff", "person frowning: Dark Skin Tone", []string{"frowning_person_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64d\U0001f3fb", "person frowning: Light Skin Tone", []string{"frowning_person_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f64d\U0001f3fc", "person frowning: Medium-Light Skin Tone", []string{"frowning_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fb\u200d\u2640\ufe0f", "woman frowning: Light Skin Tone", []string{"frowning_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fc\u200d\u2640\ufe0f", "woman frowning: Medium-Light Skin Tone", []string{"frowning_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fd\u200d\u2640\ufe0f", "woman frowning: Medium Skin Tone", []string{"frowning_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3fe\u200d\u2640\ufe0f", "woman frowning: Medium-Dark Skin Tone", []string{"frowning_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64d\U0001f3ff\u200d\u2640\ufe0f", "woman frowning: Dark Skin Tone", []string{"frowning_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f467\U0001f3fc", "girl: Medium-Light Skin Tone", []string{"girl_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f467\U0001f3fd", "girl: Medium Skin Tone", []string{"girl_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f467\U0001f3fe", "girl: Medium-Dark Skin Tone", []string{"girl_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f467\U0001f3ff", "girl: Dark Skin Tone", []string{"girl_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f467\U0001f3fb", "girl: Light Skin Tone", []string{"girl_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f467\U0001f3fc", "girl: Medium-Light Skin Tone", []string{"girl_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3cc\U0001f3ff\ufe0f", "person golfing: Dark Skin Tone", []string{"golfing_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fb\ufe0f", "person golfing: Light Skin Tone", []string{"golfing_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fc\ufe0f", "person golfing: Medium-Light Skin Tone", []string{"golfing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fd\ufe0f", "person golfing: Medium Skin Tone", []string{"golfing_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fe\ufe0f", "person golfing: Medium-Dark Skin Tone", []string{"golfing_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3cc\U0001f3ff\ufe0f", "person golfing: Dark Skin Tone", []string{"golfing_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fb\ufe0f\u200d\u2642\ufe0f", "man golfing: Light Skin Tone", []string{"golfing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fc\ufe0f\u200d\u2642\ufe0f", "man golfing: Medium-Light Skin Tone", []string{"golfing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fd\ufe0f\u200d\u2642\ufe0f", "man golfing: Medium Skin Tone", []string{"golfing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fe\ufe0f\u200d\u2642\ufe0f", "man golfing: Medium-Dark Skin Tone", []string{"golfing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3ff\ufe0f\u200d\u2642\ufe0f", "man golfing: Dark Skin Tone", []string{"golfing_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3cc\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman golfing: Light Skin Tone", []string{"golfing_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f3cc\U0001f3fc\ufe0f\u200d\u2640\ufe0f", "woman golfing: Medium-Light Skin Tone", []string{"golfing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fd\ufe0f\u200d\u2640\ufe0f", "woman golfing: Medium Skin Tone", []string{"golfing_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3fe\ufe0f\u200d\u2640\ufe0f", "woman golfing: Medium-Dark Skin Tone", []string{"golfing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cc\U0001f3ff\ufe0f\u200d\u2640\ufe0f", "woman golfing: Dark Skin Tone", []string{"golfing_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f3cc\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman golfing: Light Skin Tone", []string{"golfing_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3cc\U0001f3fc\ufe0f\u200d\u2640\ufe0f", "woman golfing: Medium-Light Skin Tone", []string{"golfing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fb", "guard: Light Skin Tone", []string{"guard_Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fc", "guard: Medium-Light Skin Tone", []string{"guard_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fd", "guard: Medium Skin Tone", []string{"guard_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fe", "guard: Medium-Dark Skin Tone", []string{"guard_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3ff", "guard: Dark Skin Tone", []string{"guard_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f482\U0001f3fd\u200d\u2642\ufe0f", "man guard: Medium Skin Tone", []string{"guardsman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f482\U0001f3fe\u200d\u2642\ufe0f", "man guard: Medium-Dark Skin Tone", []string{"guardsman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3ff\u200d\u2642\ufe0f", "man guard: Dark Skin Tone", []string{"guardsman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fb\u200d\u2642\ufe0f", "man guard: Light Skin Tone", []string{"guardsman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fc\u200d\u2642\ufe0f", "man guard: Medium-Light Skin Tone", []string{"guardsman_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f482\U0001f3fd\u200d\u2642\ufe0f", "man guard: Medium Skin Tone", []string{"guardsman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f482\U0001f3fe\u200d\u2642\ufe0f", "man guard: Medium-Dark Skin Tone", []string{"guardsman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fb\u200d\u2640\ufe0f", "woman guard: Light Skin Tone", []string{"guardswoman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fc\u200d\u2640\ufe0f", "woman guard: Medium-Light Skin Tone", []string{"guardswoman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f482\U0001f3fd\u200d\u2640\ufe0f", "woman guard: Medium Skin Tone", []string{"guardswoman_Medium_Skin_Tone"}, "12.0", false}, @@ -2116,131 +2155,131 @@ var GemojiData = Gemoji{ {"\U0001f487\U0001f3fb", "person getting haircut: Light Skin Tone", []string{"haircut_Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fc", "person getting haircut: Medium-Light Skin Tone", []string{"haircut_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fd", "person getting haircut: Medium Skin Tone", []string{"haircut_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f487\U0001f3fb\u200d\u2642\ufe0f", "man getting haircut: Light Skin Tone", []string{"haircut_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fc\u200d\u2642\ufe0f", "man getting haircut: Medium-Light Skin Tone", []string{"haircut_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fd\u200d\u2642\ufe0f", "man getting haircut: Medium Skin Tone", []string{"haircut_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fe\u200d\u2642\ufe0f", "man getting haircut: Medium-Dark Skin Tone", []string{"haircut_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3ff\u200d\u2642\ufe0f", "man getting haircut: Dark Skin Tone", []string{"haircut_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f487\U0001f3fb\u200d\u2642\ufe0f", "man getting haircut: Light Skin Tone", []string{"haircut_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f487\U0001f3ff\u200d\u2640\ufe0f", "woman getting haircut: Dark Skin Tone", []string{"haircut_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f487\U0001f3fb\u200d\u2640\ufe0f", "woman getting haircut: Light Skin Tone", []string{"haircut_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fc\u200d\u2640\ufe0f", "woman getting haircut: Medium-Light Skin Tone", []string{"haircut_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fd\u200d\u2640\ufe0f", "woman getting haircut: Medium Skin Tone", []string{"haircut_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f487\U0001f3fe\u200d\u2640\ufe0f", "woman getting haircut: Medium-Dark Skin Tone", []string{"haircut_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f487\U0001f3ff\u200d\u2640\ufe0f", "woman getting haircut: Dark Skin Tone", []string{"haircut_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f487\U0001f3fb\u200d\u2640\ufe0f", "woman getting haircut: Light Skin Tone", []string{"haircut_woman_Light_Skin_Tone"}, "12.0", false}, + {"\u270b\U0001f3ff", "raised hand: Dark Skin Tone", []string{"hand_Dark_Skin_Tone"}, "12.0", false}, + {"\u270b\U0001f3fb", "raised hand: Light Skin Tone", []string{"hand_Light_Skin_Tone"}, "12.0", false}, {"\u270b\U0001f3fc", "raised hand: Medium-Light Skin Tone", []string{"hand_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u270b\U0001f3fd", "raised hand: Medium Skin Tone", []string{"hand_Medium_Skin_Tone"}, "12.0", false}, {"\u270b\U0001f3fe", "raised hand: Medium-Dark Skin Tone", []string{"hand_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\u270b\U0001f3ff", "raised hand: Dark Skin Tone", []string{"hand_Dark_Skin_Tone"}, "12.0", false}, - {"\u270b\U0001f3fb", "raised hand: Light Skin Tone", []string{"hand_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f93e\U0001f3fd", "person playing handball: Medium Skin Tone", []string{"handball_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fe", "person playing handball: Medium-Dark Skin Tone", []string{"handball_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3ff", "person playing handball: Dark Skin Tone", []string{"handball_person_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fb", "person playing handball: Light Skin Tone", []string{"handball_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fc", "person playing handball: Medium-Light Skin Tone", []string{"handball_person_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f93e\U0001f3fd", "person playing handball: Medium Skin Tone", []string{"handball_person_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\u2695\ufe0f", "health worker: Dark Skin Tone", []string{"health_worker_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\u2695\ufe0f", "health worker: Light Skin Tone", []string{"health_worker_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\u2695\ufe0f", "health worker: Medium-Light Skin Tone", []string{"health_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\u2695\ufe0f", "health worker: Medium Skin Tone", []string{"health_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\u2695\ufe0f", "health worker: Medium-Dark Skin Tone", []string{"health_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\u2695\ufe0f", "health worker: Dark Skin Tone", []string{"health_worker_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f3c7\U0001f3fb", "horse racing: Light Skin Tone", []string{"horse_racing_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3c7\U0001f3fc", "horse racing: Medium-Light Skin Tone", []string{"horse_racing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c7\U0001f3fd", "horse racing: Medium Skin Tone", []string{"horse_racing_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c7\U0001f3fe", "horse racing: Medium-Dark Skin Tone", []string{"horse_racing_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c7\U0001f3ff", "horse racing: Dark Skin Tone", []string{"horse_racing_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3c7\U0001f3fb", "horse racing: Light Skin Tone", []string{"horse_racing_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f3c7\U0001f3fc", "horse racing: Medium-Light Skin Tone", []string{"horse_racing_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\u2696\ufe0f", "judge: Dark Skin Tone", []string{"judge_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\u2696\ufe0f", "judge: Light Skin Tone", []string{"judge_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\u2696\ufe0f", "judge: Medium-Light Skin Tone", []string{"judge_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\u2696\ufe0f", "judge: Medium Skin Tone", []string{"judge_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\u2696\ufe0f", "judge: Medium-Dark Skin Tone", []string{"judge_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\u2696\ufe0f", "judge: Dark Skin Tone", []string{"judge_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\u2696\ufe0f", "judge: Light Skin Tone", []string{"judge_Light_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fd", "person juggling: Medium Skin Tone", []string{"juggling_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fe", "person juggling: Medium-Dark Skin Tone", []string{"juggling_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3ff", "person juggling: Dark Skin Tone", []string{"juggling_person_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fb", "person juggling: Light Skin Tone", []string{"juggling_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fc", "person juggling: Medium-Light Skin Tone", []string{"juggling_person_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9ce\U0001f3fb\u200d\u2642\ufe0f", "man kneeling: Light Skin Tone", []string{"kneeling_man_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9ce\U0001f3fc\u200d\u2642\ufe0f", "man kneeling: Medium-Light Skin Tone", []string{"kneeling_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fd\u200d\u2642\ufe0f", "man kneeling: Medium Skin Tone", []string{"kneeling_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fe\u200d\u2642\ufe0f", "man kneeling: Medium-Dark Skin Tone", []string{"kneeling_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3ff\u200d\u2642\ufe0f", "man kneeling: Dark Skin Tone", []string{"kneeling_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9ce\U0001f3fb\u200d\u2642\ufe0f", "man kneeling: Light Skin Tone", []string{"kneeling_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9ce\U0001f3fc\u200d\u2642\ufe0f", "man kneeling: Medium-Light Skin Tone", []string{"kneeling_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fb", "person kneeling: Light Skin Tone", []string{"kneeling_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fc", "person kneeling: Medium-Light Skin Tone", []string{"kneeling_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fd", "person kneeling: Medium Skin Tone", []string{"kneeling_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fe", "person kneeling: Medium-Dark Skin Tone", []string{"kneeling_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3ff", "person kneeling: Dark Skin Tone", []string{"kneeling_person_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9ce\U0001f3ff\u200d\u2640\ufe0f", "woman kneeling: Dark Skin Tone", []string{"kneeling_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9ce\U0001f3fb\u200d\u2640\ufe0f", "woman kneeling: Light Skin Tone", []string{"kneeling_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fc\u200d\u2640\ufe0f", "woman kneeling: Medium-Light Skin Tone", []string{"kneeling_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fd\u200d\u2640\ufe0f", "woman kneeling: Medium Skin Tone", []string{"kneeling_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9ce\U0001f3fe\u200d\u2640\ufe0f", "woman kneeling: Medium-Dark Skin Tone", []string{"kneeling_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9ce\U0001f3ff\u200d\u2640\ufe0f", "woman kneeling: Dark Skin Tone", []string{"kneeling_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9ce\U0001f3fb\u200d\u2640\ufe0f", "woman kneeling: Light Skin Tone", []string{"kneeling_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b5\U0001f3fb", "leg: Light Skin Tone", []string{"leg_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b5\U0001f3fc", "leg: Medium-Light Skin Tone", []string{"leg_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b5\U0001f3fd", "leg: Medium Skin Tone", []string{"leg_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b5\U0001f3fe", "leg: Medium-Dark Skin Tone", []string{"leg_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b5\U0001f3ff", "leg: Dark Skin Tone", []string{"leg_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fb", "person in lotus position: Light Skin Tone", []string{"lotus_position_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fc", "person in lotus position: Medium-Light Skin Tone", []string{"lotus_position_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fd", "person in lotus position: Medium Skin Tone", []string{"lotus_position_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fe", "person in lotus position: Medium-Dark Skin Tone", []string{"lotus_position_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3ff", "person in lotus position: Dark Skin Tone", []string{"lotus_position_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fb", "person in lotus position: Light Skin Tone", []string{"lotus_position_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fc", "person in lotus position: Medium-Light Skin Tone", []string{"lotus_position_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fd\u200d\u2642\ufe0f", "man in lotus position: Medium Skin Tone", []string{"lotus_position_man_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fe\u200d\u2642\ufe0f", "man in lotus position: Medium-Dark Skin Tone", []string{"lotus_position_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3ff\u200d\u2642\ufe0f", "man in lotus position: Dark Skin Tone", []string{"lotus_position_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fb\u200d\u2642\ufe0f", "man in lotus position: Light Skin Tone", []string{"lotus_position_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fc\u200d\u2642\ufe0f", "man in lotus position: Medium-Light Skin Tone", []string{"lotus_position_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fd\u200d\u2642\ufe0f", "man in lotus position: Medium Skin Tone", []string{"lotus_position_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fe\u200d\u2642\ufe0f", "man in lotus position: Medium-Dark Skin Tone", []string{"lotus_position_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fb\u200d\u2640\ufe0f", "woman in lotus position: Light Skin Tone", []string{"lotus_position_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d8\U0001f3fc\u200d\u2640\ufe0f", "woman in lotus position: Medium-Light Skin Tone", []string{"lotus_position_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fd\u200d\u2640\ufe0f", "woman in lotus position: Medium Skin Tone", []string{"lotus_position_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3fe\u200d\u2640\ufe0f", "woman in lotus position: Medium-Dark Skin Tone", []string{"lotus_position_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d8\U0001f3ff\u200d\u2640\ufe0f", "woman in lotus position: Dark Skin Tone", []string{"lotus_position_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fb\u200d\u2640\ufe0f", "woman in lotus position: Light Skin Tone", []string{"lotus_position_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d8\U0001f3fc\u200d\u2640\ufe0f", "woman in lotus position: Medium-Light Skin Tone", []string{"lotus_position_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f91f\U0001f3ff", "love-you gesture: Dark Skin Tone", []string{"love_you_gesture_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f91f\U0001f3fb", "love-you gesture: Light Skin Tone", []string{"love_you_gesture_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91f\U0001f3fc", "love-you gesture: Medium-Light Skin Tone", []string{"love_you_gesture_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f91f\U0001f3fd", "love-you gesture: Medium Skin Tone", []string{"love_you_gesture_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f91f\U0001f3fe", "love-you gesture: Medium-Dark Skin Tone", []string{"love_you_gesture_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f91f\U0001f3ff", "love-you gesture: Dark Skin Tone", []string{"love_you_gesture_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f91f\U0001f3fb", "love-you gesture: Light Skin Tone", []string{"love_you_gesture_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fb", "mage: Light Skin Tone", []string{"mage_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fc", "mage: Medium-Light Skin Tone", []string{"mage_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fd", "mage: Medium Skin Tone", []string{"mage_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fe", "mage: Medium-Dark Skin Tone", []string{"mage_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3ff", "mage: Dark Skin Tone", []string{"mage_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d9\U0001f3fe\u200d\u2642\ufe0f", "man mage: Medium-Dark Skin Tone", []string{"mage_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d9\U0001f3ff\u200d\u2642\ufe0f", "man mage: Dark Skin Tone", []string{"mage_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fb\u200d\u2642\ufe0f", "man mage: Light Skin Tone", []string{"mage_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fc\u200d\u2642\ufe0f", "man mage: Medium-Light Skin Tone", []string{"mage_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fd\u200d\u2642\ufe0f", "man mage: Medium Skin Tone", []string{"mage_man_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d9\U0001f3fb\u200d\u2640\ufe0f", "woman mage: Light Skin Tone", []string{"mage_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d9\U0001f3fc\u200d\u2640\ufe0f", "woman mage: Medium-Light Skin Tone", []string{"mage_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d9\U0001f3fe\u200d\u2642\ufe0f", "man mage: Medium-Dark Skin Tone", []string{"mage_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d9\U0001f3ff\u200d\u2642\ufe0f", "man mage: Dark Skin Tone", []string{"mage_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fd\u200d\u2640\ufe0f", "woman mage: Medium Skin Tone", []string{"mage_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3fe\u200d\u2640\ufe0f", "woman mage: Medium-Dark Skin Tone", []string{"mage_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d9\U0001f3ff\u200d\u2640\ufe0f", "woman mage: Dark Skin Tone", []string{"mage_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d9\U0001f3fb\u200d\u2640\ufe0f", "woman mage: Light Skin Tone", []string{"mage_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d9\U0001f3fc\u200d\u2640\ufe0f", "woman mage: Medium-Light Skin Tone", []string{"mage_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f575\U0001f3fb\ufe0f\u200d\u2642\ufe0f", "man detective: Light Skin Tone", []string{"male_detective_Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fc\ufe0f\u200d\u2642\ufe0f", "man detective: Medium-Light Skin Tone", []string{"male_detective_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fd\ufe0f\u200d\u2642\ufe0f", "man detective: Medium Skin Tone", []string{"male_detective_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3fe\ufe0f\u200d\u2642\ufe0f", "man detective: Medium-Dark Skin Tone", []string{"male_detective_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f575\U0001f3ff\ufe0f\u200d\u2642\ufe0f", "man detective: Dark Skin Tone", []string{"male_detective_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f575\U0001f3fb\ufe0f\u200d\u2642\ufe0f", "man detective: Light Skin Tone", []string{"male_detective_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe", "man: Medium-Dark Skin Tone", []string{"man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff", "man: Dark Skin Tone", []string{"man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb", "man: Light Skin Tone", []string{"man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc", "man: Medium-Light Skin Tone", []string{"man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd", "man: Medium Skin Tone", []string{"man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe", "man: Medium-Dark Skin Tone", []string{"man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff", "man: Dark Skin Tone", []string{"man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fd\u200d\U0001f3a8", "man artist: Medium Skin Tone", []string{"man_artist_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f3a8", "man artist: Medium-Dark Skin Tone", []string{"man_artist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f3a8", "man artist: Dark Skin Tone", []string{"man_artist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f3a8", "man artist: Light Skin Tone", []string{"man_artist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f3a8", "man artist: Medium-Light Skin Tone", []string{"man_artist_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fd\u200d\U0001f3a8", "man artist: Medium Skin Tone", []string{"man_artist_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f3a8", "man artist: Medium-Dark Skin Tone", []string{"man_artist_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\U0001f680", "man astronaut: Medium-Light Skin Tone", []string{"man_astronaut_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f680", "man astronaut: Medium Skin Tone", []string{"man_astronaut_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f680", "man astronaut: Medium-Dark Skin Tone", []string{"man_astronaut_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f680", "man astronaut: Dark Skin Tone", []string{"man_astronaut_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f680", "man astronaut: Light Skin Tone", []string{"man_astronaut_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\U0001f680", "man astronaut: Medium-Light Skin Tone", []string{"man_astronaut_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f938\U0001f3fb\u200d\u2642\ufe0f", "man cartwheeling: Light Skin Tone", []string{"man_cartwheeling_Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fc\u200d\u2642\ufe0f", "man cartwheeling: Medium-Light Skin Tone", []string{"man_cartwheeling_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fd\u200d\u2642\ufe0f", "man cartwheeling: Medium Skin Tone", []string{"man_cartwheeling_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fe\u200d\u2642\ufe0f", "man cartwheeling: Medium-Dark Skin Tone", []string{"man_cartwheeling_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3ff\u200d\u2642\ufe0f", "man cartwheeling: Dark Skin Tone", []string{"man_cartwheeling_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f938\U0001f3fb\u200d\u2642\ufe0f", "man cartwheeling: Light Skin Tone", []string{"man_cartwheeling_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f373", "man cook: Medium-Dark Skin Tone", []string{"man_cook_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f373", "man cook: Dark Skin Tone", []string{"man_cook_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f373", "man cook: Light Skin Tone", []string{"man_cook_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f373", "man cook: Medium-Light Skin Tone", []string{"man_cook_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f373", "man cook: Medium Skin Tone", []string{"man_cook_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f373", "man cook: Medium-Dark Skin Tone", []string{"man_cook_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f57a\U0001f3fb", "man dancing: Light Skin Tone", []string{"man_dancing_Light_Skin_Tone"}, "12.0", false}, {"\U0001f57a\U0001f3fc", "man dancing: Medium-Light Skin Tone", []string{"man_dancing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f57a\U0001f3fd", "man dancing: Medium Skin Tone", []string{"man_dancing_Medium_Skin_Tone"}, "12.0", false}, @@ -2251,61 +2290,61 @@ var GemojiData = Gemoji{ {"\U0001f926\U0001f3fb\u200d\u2642\ufe0f", "man facepalming: Light Skin Tone", []string{"man_facepalming_Light_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fc\u200d\u2642\ufe0f", "man facepalming: Medium-Light Skin Tone", []string{"man_facepalming_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fd\u200d\u2642\ufe0f", "man facepalming: Medium Skin Tone", []string{"man_facepalming_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f3ed", "man factory worker: Dark Skin Tone", []string{"man_factory_worker_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f3ed", "man factory worker: Light Skin Tone", []string{"man_factory_worker_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f3ed", "man factory worker: Medium-Light Skin Tone", []string{"man_factory_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f3ed", "man factory worker: Medium Skin Tone", []string{"man_factory_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f3ed", "man factory worker: Medium-Dark Skin Tone", []string{"man_factory_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f3ed", "man factory worker: Dark Skin Tone", []string{"man_factory_worker_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f33e", "man farmer: Light Skin Tone", []string{"man_farmer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f33e", "man farmer: Medium-Light Skin Tone", []string{"man_farmer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f33e", "man farmer: Medium Skin Tone", []string{"man_farmer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f33e", "man farmer: Medium-Dark Skin Tone", []string{"man_farmer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f33e", "man farmer: Dark Skin Tone", []string{"man_farmer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f692", "man firefighter: Dark Skin Tone", []string{"man_firefighter_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f692", "man firefighter: Light Skin Tone", []string{"man_firefighter_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f692", "man firefighter: Medium-Light Skin Tone", []string{"man_firefighter_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f692", "man firefighter: Medium Skin Tone", []string{"man_firefighter_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f692", "man firefighter: Medium-Dark Skin Tone", []string{"man_firefighter_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f692", "man firefighter: Dark Skin Tone", []string{"man_firefighter_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\u2695\ufe0f", "man health worker: Medium-Dark Skin Tone", []string{"man_health_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\u2695\ufe0f", "man health worker: Dark Skin Tone", []string{"man_health_worker_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\u2695\ufe0f", "man health worker: Light Skin Tone", []string{"man_health_worker_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\u2695\ufe0f", "man health worker: Medium-Light Skin Tone", []string{"man_health_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\u2695\ufe0f", "man health worker: Medium Skin Tone", []string{"man_health_worker_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\u2695\ufe0f", "man health worker: Medium-Dark Skin Tone", []string{"man_health_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\u2695\ufe0f", "man health worker: Dark Skin Tone", []string{"man_health_worker_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\U0001f9bd", "man in manual wheelchair: Light Skin Tone", []string{"man_in_manual_wheelchair_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\U0001f9bd", "man in manual wheelchair: Medium-Light Skin Tone", []string{"man_in_manual_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9bd", "man in manual wheelchair: Medium Skin Tone", []string{"man_in_manual_wheelchair_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f9bd", "man in manual wheelchair: Medium-Dark Skin Tone", []string{"man_in_manual_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f9bd", "man in manual wheelchair: Dark Skin Tone", []string{"man_in_manual_wheelchair_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\U0001f9bc", "man in motorized wheelchair: Light Skin Tone", []string{"man_in_motorized_wheelchair_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\U0001f9bc", "man in motorized wheelchair: Medium-Light Skin Tone", []string{"man_in_motorized_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\U0001f9bd", "man in manual wheelchair: Light Skin Tone", []string{"man_in_manual_wheelchair_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\U0001f9bd", "man in manual wheelchair: Medium-Light Skin Tone", []string{"man_in_manual_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9bc", "man in motorized wheelchair: Medium Skin Tone", []string{"man_in_motorized_wheelchair_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f9bc", "man in motorized wheelchair: Medium-Dark Skin Tone", []string{"man_in_motorized_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f9bc", "man in motorized wheelchair: Dark Skin Tone", []string{"man_in_motorized_wheelchair_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\U0001f9bc", "man in motorized wheelchair: Light Skin Tone", []string{"man_in_motorized_wheelchair_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\U0001f9bc", "man in motorized wheelchair: Medium-Light Skin Tone", []string{"man_in_motorized_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\u2696\ufe0f", "man judge: Light Skin Tone", []string{"man_judge_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\u2696\ufe0f", "man judge: Medium-Light Skin Tone", []string{"man_judge_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\u2696\ufe0f", "man judge: Medium Skin Tone", []string{"man_judge_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\u2696\ufe0f", "man judge: Medium-Dark Skin Tone", []string{"man_judge_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\u2696\ufe0f", "man judge: Dark Skin Tone", []string{"man_judge_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\u2696\ufe0f", "man judge: Light Skin Tone", []string{"man_judge_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\u2696\ufe0f", "man judge: Medium-Light Skin Tone", []string{"man_judge_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f939\U0001f3fc\u200d\u2642\ufe0f", "man juggling: Medium-Light Skin Tone", []string{"man_juggling_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f939\U0001f3fd\u200d\u2642\ufe0f", "man juggling: Medium Skin Tone", []string{"man_juggling_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fe\u200d\u2642\ufe0f", "man juggling: Medium-Dark Skin Tone", []string{"man_juggling_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3ff\u200d\u2642\ufe0f", "man juggling: Dark Skin Tone", []string{"man_juggling_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fb\u200d\u2642\ufe0f", "man juggling: Light Skin Tone", []string{"man_juggling_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f939\U0001f3fc\u200d\u2642\ufe0f", "man juggling: Medium-Light Skin Tone", []string{"man_juggling_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f939\U0001f3fd\u200d\u2642\ufe0f", "man juggling: Medium Skin Tone", []string{"man_juggling_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\U0001f527", "man mechanic: Light Skin Tone", []string{"man_mechanic_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\U0001f527", "man mechanic: Medium-Light Skin Tone", []string{"man_mechanic_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f527", "man mechanic: Medium Skin Tone", []string{"man_mechanic_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f527", "man mechanic: Medium-Dark Skin Tone", []string{"man_mechanic_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f527", "man mechanic: Dark Skin Tone", []string{"man_mechanic_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\U0001f527", "man mechanic: Light Skin Tone", []string{"man_mechanic_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\U0001f527", "man mechanic: Medium-Light Skin Tone", []string{"man_mechanic_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f4bc", "man office worker: Light Skin Tone", []string{"man_office_worker_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f4bc", "man office worker: Medium-Light Skin Tone", []string{"man_office_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f4bc", "man office worker: Medium Skin Tone", []string{"man_office_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f4bc", "man office worker: Medium-Dark Skin Tone", []string{"man_office_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f4bc", "man office worker: Dark Skin Tone", []string{"man_office_worker_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\u2708\ufe0f", "man pilot: Light Skin Tone", []string{"man_pilot_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\u2708\ufe0f", "man pilot: Medium-Light Skin Tone", []string{"man_pilot_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\u2708\ufe0f", "man pilot: Medium Skin Tone", []string{"man_pilot_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\u2708\ufe0f", "man pilot: Medium-Dark Skin Tone", []string{"man_pilot_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\u2708\ufe0f", "man pilot: Dark Skin Tone", []string{"man_pilot_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\u2708\ufe0f", "man pilot: Light Skin Tone", []string{"man_pilot_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\u2708\ufe0f", "man pilot: Medium-Light Skin Tone", []string{"man_pilot_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fb\u200d\u2642\ufe0f", "man playing handball: Light Skin Tone", []string{"man_playing_handball_Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fc\u200d\u2642\ufe0f", "man playing handball: Medium-Light Skin Tone", []string{"man_playing_handball_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fd\u200d\u2642\ufe0f", "man playing handball: Medium Skin Tone", []string{"man_playing_handball_Medium_Skin_Tone"}, "12.0", false}, @@ -2321,91 +2360,91 @@ var GemojiData = Gemoji{ {"\U0001f468\U0001f3fd\u200d\U0001f52c", "man scientist: Medium Skin Tone", []string{"man_scientist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f52c", "man scientist: Medium-Dark Skin Tone", []string{"man_scientist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f52c", "man scientist: Dark Skin Tone", []string{"man_scientist_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f937\U0001f3fe\u200d\u2642\ufe0f", "man shrugging: Medium-Dark Skin Tone", []string{"man_shrugging_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f937\U0001f3ff\u200d\u2642\ufe0f", "man shrugging: Dark Skin Tone", []string{"man_shrugging_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fb\u200d\u2642\ufe0f", "man shrugging: Light Skin Tone", []string{"man_shrugging_Light_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fc\u200d\u2642\ufe0f", "man shrugging: Medium-Light Skin Tone", []string{"man_shrugging_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fd\u200d\u2642\ufe0f", "man shrugging: Medium Skin Tone", []string{"man_shrugging_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f937\U0001f3fe\u200d\u2642\ufe0f", "man shrugging: Medium-Dark Skin Tone", []string{"man_shrugging_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f937\U0001f3ff\u200d\u2642\ufe0f", "man shrugging: Dark Skin Tone", []string{"man_shrugging_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f3a4", "man singer: Light Skin Tone", []string{"man_singer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f3a4", "man singer: Medium-Light Skin Tone", []string{"man_singer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f3a4", "man singer: Medium Skin Tone", []string{"man_singer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f3a4", "man singer: Medium-Dark Skin Tone", []string{"man_singer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f3a4", "man singer: Dark Skin Tone", []string{"man_singer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f393", "man student: Medium-Dark Skin Tone", []string{"man_student_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f393", "man student: Dark Skin Tone", []string{"man_student_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f393", "man student: Light Skin Tone", []string{"man_student_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f393", "man student: Medium-Light Skin Tone", []string{"man_student_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f393", "man student: Medium Skin Tone", []string{"man_student_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f393", "man student: Medium-Dark Skin Tone", []string{"man_student_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f393", "man student: Dark Skin Tone", []string{"man_student_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f3eb", "man teacher: Dark Skin Tone", []string{"man_teacher_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\U0001f3eb", "man teacher: Light Skin Tone", []string{"man_teacher_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f3eb", "man teacher: Medium-Light Skin Tone", []string{"man_teacher_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f3eb", "man teacher: Medium Skin Tone", []string{"man_teacher_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f3eb", "man teacher: Medium-Dark Skin Tone", []string{"man_teacher_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f3eb", "man teacher: Dark Skin Tone", []string{"man_teacher_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\U0001f3eb", "man teacher: Light Skin Tone", []string{"man_teacher_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f4bb", "man technologist: Light Skin Tone", []string{"man_technologist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f4bb", "man technologist: Medium-Light Skin Tone", []string{"man_technologist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f4bb", "man technologist: Medium Skin Tone", []string{"man_technologist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f4bb", "man technologist: Medium-Dark Skin Tone", []string{"man_technologist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f4bb", "man technologist: Dark Skin Tone", []string{"man_technologist_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f472\U0001f3fe", "person with skullcap: Medium-Dark Skin Tone", []string{"man_with_gua_pi_mao_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f472\U0001f3ff", "person with skullcap: Dark Skin Tone", []string{"man_with_gua_pi_mao_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f472\U0001f3fb", "person with skullcap: Light Skin Tone", []string{"man_with_gua_pi_mao_Light_Skin_Tone"}, "12.0", false}, {"\U0001f472\U0001f3fc", "person with skullcap: Medium-Light Skin Tone", []string{"man_with_gua_pi_mao_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f472\U0001f3fd", "person with skullcap: Medium Skin Tone", []string{"man_with_gua_pi_mao_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f472\U0001f3fe", "person with skullcap: Medium-Dark Skin Tone", []string{"man_with_gua_pi_mao_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f472\U0001f3ff", "person with skullcap: Dark Skin Tone", []string{"man_with_gua_pi_mao_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fe\u200d\U0001f9af", "man with white cane: Medium-Dark Skin Tone", []string{"man_with_probing_cane_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3ff\u200d\U0001f9af", "man with white cane: Dark Skin Tone", []string{"man_with_probing_cane_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f9af", "man with white cane: Light Skin Tone", []string{"man_with_probing_cane_Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f9af", "man with white cane: Medium-Light Skin Tone", []string{"man_with_probing_cane_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9af", "man with white cane: Medium Skin Tone", []string{"man_with_probing_cane_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fe\u200d\U0001f9af", "man with white cane: Medium-Dark Skin Tone", []string{"man_with_probing_cane_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3ff\u200d\U0001f9af", "man with white cane: Dark Skin Tone", []string{"man_with_probing_cane_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3fc\u200d\u2642\ufe0f", "man wearing turban: Medium-Light Skin Tone", []string{"man_with_turban_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3fd\u200d\u2642\ufe0f", "man wearing turban: Medium Skin Tone", []string{"man_with_turban_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fe\u200d\u2642\ufe0f", "man wearing turban: Medium-Dark Skin Tone", []string{"man_with_turban_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3ff\u200d\u2642\ufe0f", "man wearing turban: Dark Skin Tone", []string{"man_with_turban_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fb\u200d\u2642\ufe0f", "man wearing turban: Light Skin Tone", []string{"man_with_turban_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3fc\u200d\u2642\ufe0f", "man wearing turban: Medium-Light Skin Tone", []string{"man_with_turban_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3fd\u200d\u2642\ufe0f", "man wearing turban: Medium Skin Tone", []string{"man_with_turban_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fb", "person getting massage: Light Skin Tone", []string{"massage_Light_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fc", "person getting massage: Medium-Light Skin Tone", []string{"massage_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fd", "person getting massage: Medium Skin Tone", []string{"massage_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fe", "person getting massage: Medium-Dark Skin Tone", []string{"massage_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3ff", "person getting massage: Dark Skin Tone", []string{"massage_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f486\U0001f3fe\u200d\u2642\ufe0f", "man getting massage: Medium-Dark Skin Tone", []string{"massage_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3ff\u200d\u2642\ufe0f", "man getting massage: Dark Skin Tone", []string{"massage_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fb\u200d\u2642\ufe0f", "man getting massage: Light Skin Tone", []string{"massage_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fc\u200d\u2642\ufe0f", "man getting massage: Medium-Light Skin Tone", []string{"massage_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fd\u200d\u2642\ufe0f", "man getting massage: Medium Skin Tone", []string{"massage_man_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f486\U0001f3fe\u200d\u2642\ufe0f", "man getting massage: Medium-Dark Skin Tone", []string{"massage_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f486\U0001f3fc\u200d\u2640\ufe0f", "woman getting massage: Medium-Light Skin Tone", []string{"massage_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fd\u200d\u2640\ufe0f", "woman getting massage: Medium Skin Tone", []string{"massage_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fe\u200d\u2640\ufe0f", "woman getting massage: Medium-Dark Skin Tone", []string{"massage_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3ff\u200d\u2640\ufe0f", "woman getting massage: Dark Skin Tone", []string{"massage_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f486\U0001f3fb\u200d\u2640\ufe0f", "woman getting massage: Light Skin Tone", []string{"massage_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f486\U0001f3fc\u200d\u2640\ufe0f", "woman getting massage: Medium-Light Skin Tone", []string{"massage_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fe\u200d\U0001f527", "mechanic: Medium-Dark Skin Tone", []string{"mechanic_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\U0001f527", "mechanic: Dark Skin Tone", []string{"mechanic_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f527", "mechanic: Light Skin Tone", []string{"mechanic_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f527", "mechanic: Medium-Light Skin Tone", []string{"mechanic_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f527", "mechanic: Medium Skin Tone", []string{"mechanic_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fe\u200d\U0001f527", "mechanic: Medium-Dark Skin Tone", []string{"mechanic_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\U0001f527", "mechanic: Dark Skin Tone", []string{"mechanic_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9dc\U0001f3ff\u200d\u2640\ufe0f", "mermaid: Dark Skin Tone", []string{"mermaid_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fb\u200d\u2640\ufe0f", "mermaid: Light Skin Tone", []string{"mermaid_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fc\u200d\u2640\ufe0f", "mermaid: Medium-Light Skin Tone", []string{"mermaid_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fd\u200d\u2640\ufe0f", "mermaid: Medium Skin Tone", []string{"mermaid_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fe\u200d\u2640\ufe0f", "mermaid: Medium-Dark Skin Tone", []string{"mermaid_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9dc\U0001f3ff\u200d\u2640\ufe0f", "mermaid: Dark Skin Tone", []string{"mermaid_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9dc\U0001f3fe\u200d\u2642\ufe0f", "merman: Medium-Dark Skin Tone", []string{"merman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9dc\U0001f3ff\u200d\u2642\ufe0f", "merman: Dark Skin Tone", []string{"merman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fb\u200d\u2642\ufe0f", "merman: Light Skin Tone", []string{"merman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fc\u200d\u2642\ufe0f", "merman: Medium-Light Skin Tone", []string{"merman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fd\u200d\u2642\ufe0f", "merman: Medium Skin Tone", []string{"merman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9dc\U0001f3fe\u200d\u2642\ufe0f", "merman: Medium-Dark Skin Tone", []string{"merman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9dc\U0001f3ff\u200d\u2642\ufe0f", "merman: Dark Skin Tone", []string{"merman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9dc\U0001f3fb", "merperson: Light Skin Tone", []string{"merperson_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fc", "merperson: Medium-Light Skin Tone", []string{"merperson_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fd", "merperson: Medium Skin Tone", []string{"merperson_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3fe", "merperson: Medium-Dark Skin Tone", []string{"merperson_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9dc\U0001f3ff", "merperson: Dark Skin Tone", []string{"merperson_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9dc\U0001f3fb", "merperson: Light Skin Tone", []string{"merperson_Light_Skin_Tone"}, "12.0", false}, {"\U0001f918\U0001f3fc", "sign of the horns: Medium-Light Skin Tone", []string{"metal_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f918\U0001f3fd", "sign of the horns: Medium Skin Tone", []string{"metal_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f918\U0001f3fe", "sign of the horns: Medium-Dark Skin Tone", []string{"metal_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f918\U0001f3ff", "sign of the horns: Dark Skin Tone", []string{"metal_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f918\U0001f3fb", "sign of the horns: Light Skin Tone", []string{"metal_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f595\U0001f3fb", "middle finger: Light Skin Tone", []string{"middle_finger_Light_Skin_Tone"}, "12.0", false}, {"\U0001f595\U0001f3fc", "middle finger: Medium-Light Skin Tone", []string{"middle_finger_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f595\U0001f3fd", "middle finger: Medium Skin Tone", []string{"middle_finger_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f595\U0001f3fe", "middle finger: Medium-Dark Skin Tone", []string{"middle_finger_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f595\U0001f3ff", "middle finger: Dark Skin Tone", []string{"middle_finger_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f595\U0001f3fb", "middle finger: Light Skin Tone", []string{"middle_finger_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fe", "person mountain biking: Medium-Dark Skin Tone", []string{"mountain_bicyclist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3ff", "person mountain biking: Dark Skin Tone", []string{"mountain_bicyclist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fb", "person mountain biking: Light Skin Tone", []string{"mountain_bicyclist_Light_Skin_Tone"}, "12.0", false}, @@ -2416,36 +2455,36 @@ var GemojiData = Gemoji{ {"\U0001f6b5\U0001f3fd\u200d\u2642\ufe0f", "man mountain biking: Medium Skin Tone", []string{"mountain_biking_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fe\u200d\u2642\ufe0f", "man mountain biking: Medium-Dark Skin Tone", []string{"mountain_biking_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3ff\u200d\u2642\ufe0f", "man mountain biking: Dark Skin Tone", []string{"mountain_biking_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6b5\U0001f3fe\u200d\u2640\ufe0f", "woman mountain biking: Medium-Dark Skin Tone", []string{"mountain_biking_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6b5\U0001f3ff\u200d\u2640\ufe0f", "woman mountain biking: Dark Skin Tone", []string{"mountain_biking_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fb\u200d\u2640\ufe0f", "woman mountain biking: Light Skin Tone", []string{"mountain_biking_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fc\u200d\u2640\ufe0f", "woman mountain biking: Medium-Light Skin Tone", []string{"mountain_biking_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b5\U0001f3fd\u200d\u2640\ufe0f", "woman mountain biking: Medium Skin Tone", []string{"mountain_biking_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f6b5\U0001f3fe\u200d\u2640\ufe0f", "woman mountain biking: Medium-Dark Skin Tone", []string{"mountain_biking_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6b5\U0001f3ff\u200d\u2640\ufe0f", "woman mountain biking: Dark Skin Tone", []string{"mountain_biking_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f936\U0001f3fb", "Mrs. Claus: Light Skin Tone", []string{"mrs_claus_Light_Skin_Tone"}, "12.0", false}, {"\U0001f936\U0001f3fc", "Mrs. Claus: Medium-Light Skin Tone", []string{"mrs_claus_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f936\U0001f3fd", "Mrs. Claus: Medium Skin Tone", []string{"mrs_claus_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f936\U0001f3fe", "Mrs. Claus: Medium-Dark Skin Tone", []string{"mrs_claus_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f936\U0001f3ff", "Mrs. Claus: Dark Skin Tone", []string{"mrs_claus_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f4aa\U0001f3ff", "flexed biceps: Dark Skin Tone", []string{"muscle_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f4aa\U0001f3fb", "flexed biceps: Light Skin Tone", []string{"muscle_Light_Skin_Tone"}, "12.0", false}, {"\U0001f4aa\U0001f3fc", "flexed biceps: Medium-Light Skin Tone", []string{"muscle_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f4aa\U0001f3fd", "flexed biceps: Medium Skin Tone", []string{"muscle_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f4aa\U0001f3fe", "flexed biceps: Medium-Dark Skin Tone", []string{"muscle_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f485\U0001f3ff", "nail polish: Dark Skin Tone", []string{"nail_care_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f4aa\U0001f3ff", "flexed biceps: Dark Skin Tone", []string{"muscle_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f485\U0001f3fb", "nail polish: Light Skin Tone", []string{"nail_care_Light_Skin_Tone"}, "12.0", false}, {"\U0001f485\U0001f3fc", "nail polish: Medium-Light Skin Tone", []string{"nail_care_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f485\U0001f3fd", "nail polish: Medium Skin Tone", []string{"nail_care_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f485\U0001f3fe", "nail polish: Medium-Dark Skin Tone", []string{"nail_care_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f485\U0001f3ff", "nail polish: Dark Skin Tone", []string{"nail_care_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f645\U0001f3fb", "person gesturing NO: Light Skin Tone", []string{"no_good_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f645\U0001f3fc", "person gesturing NO: Medium-Light Skin Tone", []string{"no_good_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fd", "person gesturing NO: Medium Skin Tone", []string{"no_good_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fe", "person gesturing NO: Medium-Dark Skin Tone", []string{"no_good_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3ff", "person gesturing NO: Dark Skin Tone", []string{"no_good_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f645\U0001f3fb", "person gesturing NO: Light Skin Tone", []string{"no_good_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f645\U0001f3fc", "person gesturing NO: Medium-Light Skin Tone", []string{"no_good_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f645\U0001f3fc\u200d\u2642\ufe0f", "man gesturing NO: Medium-Light Skin Tone", []string{"no_good_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fd\u200d\u2642\ufe0f", "man gesturing NO: Medium Skin Tone", []string{"no_good_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fe\u200d\u2642\ufe0f", "man gesturing NO: Medium-Dark Skin Tone", []string{"no_good_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3ff\u200d\u2642\ufe0f", "man gesturing NO: Dark Skin Tone", []string{"no_good_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fb\u200d\u2642\ufe0f", "man gesturing NO: Light Skin Tone", []string{"no_good_man_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f645\U0001f3fc\u200d\u2642\ufe0f", "man gesturing NO: Medium-Light Skin Tone", []string{"no_good_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fb\u200d\u2640\ufe0f", "woman gesturing NO: Light Skin Tone", []string{"no_good_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fc\u200d\u2640\ufe0f", "woman gesturing NO: Medium-Light Skin Tone", []string{"no_good_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f645\U0001f3fd\u200d\u2640\ufe0f", "woman gesturing NO: Medium Skin Tone", []string{"no_good_woman_Medium_Skin_Tone"}, "12.0", false}, @@ -2456,31 +2495,31 @@ var GemojiData = Gemoji{ {"\U0001f443\U0001f3fd", "nose: Medium Skin Tone", []string{"nose_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f443\U0001f3fe", "nose: Medium-Dark Skin Tone", []string{"nose_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f443\U0001f3ff", "nose: Dark Skin Tone", []string{"nose_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f4bc", "office worker: Light Skin Tone", []string{"office_worker_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f4bc", "office worker: Medium-Light Skin Tone", []string{"office_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f4bc", "office worker: Medium Skin Tone", []string{"office_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f4bc", "office worker: Medium-Dark Skin Tone", []string{"office_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f4bc", "office worker: Dark Skin Tone", []string{"office_worker_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f44c\U0001f3fc", "OK hand: Medium-Light Skin Tone", []string{"ok_hand_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f44c\U0001f3fd", "OK hand: Medium Skin Tone", []string{"ok_hand_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f4bc", "office worker: Light Skin Tone", []string{"office_worker_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f4bc", "office worker: Medium-Light Skin Tone", []string{"office_worker_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44c\U0001f3fe", "OK hand: Medium-Dark Skin Tone", []string{"ok_hand_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f44c\U0001f3ff", "OK hand: Dark Skin Tone", []string{"ok_hand_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f44c\U0001f3fb", "OK hand: Light Skin Tone", []string{"ok_hand_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f44c\U0001f3fc", "OK hand: Medium-Light Skin Tone", []string{"ok_hand_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f44c\U0001f3fd", "OK hand: Medium Skin Tone", []string{"ok_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fb\u200d\u2642\ufe0f", "man gesturing OK: Light Skin Tone", []string{"ok_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fc\u200d\u2642\ufe0f", "man gesturing OK: Medium-Light Skin Tone", []string{"ok_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fd\u200d\u2642\ufe0f", "man gesturing OK: Medium Skin Tone", []string{"ok_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fe\u200d\u2642\ufe0f", "man gesturing OK: Medium-Dark Skin Tone", []string{"ok_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3ff\u200d\u2642\ufe0f", "man gesturing OK: Dark Skin Tone", []string{"ok_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f646\U0001f3ff", "person gesturing OK: Dark Skin Tone", []string{"ok_person_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fb", "person gesturing OK: Light Skin Tone", []string{"ok_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fc", "person gesturing OK: Medium-Light Skin Tone", []string{"ok_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fd", "person gesturing OK: Medium Skin Tone", []string{"ok_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fe", "person gesturing OK: Medium-Dark Skin Tone", []string{"ok_person_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f646\U0001f3ff", "person gesturing OK: Dark Skin Tone", []string{"ok_person_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f646\U0001f3fc\u200d\u2640\ufe0f", "woman gesturing OK: Medium-Light Skin Tone", []string{"ok_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f646\U0001f3fd\u200d\u2640\ufe0f", "woman gesturing OK: Medium Skin Tone", []string{"ok_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fe\u200d\u2640\ufe0f", "woman gesturing OK: Medium-Dark Skin Tone", []string{"ok_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3ff\u200d\u2640\ufe0f", "woman gesturing OK: Dark Skin Tone", []string{"ok_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f646\U0001f3fb\u200d\u2640\ufe0f", "woman gesturing OK: Light Skin Tone", []string{"ok_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f646\U0001f3fc\u200d\u2640\ufe0f", "woman gesturing OK: Medium-Light Skin Tone", []string{"ok_woman_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f646\U0001f3fd\u200d\u2640\ufe0f", "woman gesturing OK: Medium Skin Tone", []string{"ok_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d3\U0001f3fb", "older person: Light Skin Tone", []string{"older_adult_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d3\U0001f3fc", "older person: Medium-Light Skin Tone", []string{"older_adult_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d3\U0001f3fd", "older person: Medium Skin Tone", []string{"older_adult_Medium_Skin_Tone"}, "12.0", false}, @@ -2496,206 +2535,206 @@ var GemojiData = Gemoji{ {"\U0001f475\U0001f3fd", "old woman: Medium Skin Tone", []string{"older_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f475\U0001f3fe", "old woman: Medium-Dark Skin Tone", []string{"older_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f475\U0001f3ff", "old woman: Dark Skin Tone", []string{"older_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f450\U0001f3fb", "open hands: Light Skin Tone", []string{"open_hands_Light_Skin_Tone"}, "12.0", false}, {"\U0001f450\U0001f3fc", "open hands: Medium-Light Skin Tone", []string{"open_hands_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f450\U0001f3fd", "open hands: Medium Skin Tone", []string{"open_hands_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f450\U0001f3fe", "open hands: Medium-Dark Skin Tone", []string{"open_hands_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f450\U0001f3ff", "open hands: Dark Skin Tone", []string{"open_hands_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f450\U0001f3fb", "open hands: Light Skin Tone", []string{"open_hands_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f932\U0001f3fd", "palms up together: Medium Skin Tone", []string{"palms_up_together_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f932\U0001f3fe", "palms up together: Medium-Dark Skin Tone", []string{"palms_up_together_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f932\U0001f3ff", "palms up together: Dark Skin Tone", []string{"palms_up_together_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f932\U0001f3fb", "palms up together: Light Skin Tone", []string{"palms_up_together_Light_Skin_Tone"}, "12.0", false}, {"\U0001f932\U0001f3fc", "palms up together: Medium-Light Skin Tone", []string{"palms_up_together_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f932\U0001f3fd", "palms up together: Medium Skin Tone", []string{"palms_up_together_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Light Skin Tone", []string{"people_holding_hands_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Medium-Light Skin Tone", []string{"people_holding_hands_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Medium Skin Tone", []string{"people_holding_hands_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Medium-Dark Skin Tone", []string{"people_holding_hands_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Dark Skin Tone", []string{"people_holding_hands_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Light Skin Tone", []string{"people_holding_hands_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f91d\u200d\U0001f9d1", "people holding hands: Medium-Light Skin Tone", []string{"people_holding_hands_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fd\u200d\U0001f9b2", "person: bald: Medium Skin Tone", []string{"person_bald_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fe\u200d\U0001f9b2", "person: bald: Medium-Dark Skin Tone", []string{"person_bald_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f9b2", "person: bald: Dark Skin Tone", []string{"person_bald_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f9b2", "person: bald: Light Skin Tone", []string{"person_bald_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9b2", "person: bald: Medium-Light Skin Tone", []string{"person_bald_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f9b1", "person: curly hair: Light Skin Tone", []string{"person_curly_hair_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f9b1", "person: curly hair: Medium-Light Skin Tone", []string{"person_curly_hair_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fd\u200d\U0001f9b2", "person: bald: Medium Skin Tone", []string{"person_bald_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fe\u200d\U0001f9b2", "person: bald: Medium-Dark Skin Tone", []string{"person_bald_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9b1", "person: curly hair: Medium Skin Tone", []string{"person_curly_hair_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f9b1", "person: curly hair: Medium-Dark Skin Tone", []string{"person_curly_hair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f9b1", "person: curly hair: Dark Skin Tone", []string{"person_curly_hair_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f9b1", "person: curly hair: Light Skin Tone", []string{"person_curly_hair_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f9b1", "person: curly hair: Medium-Light Skin Tone", []string{"person_curly_hair_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fe\u200d\U0001f9bd", "person in manual wheelchair: Medium-Dark Skin Tone", []string{"person_in_manual_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\U0001f9bd", "person in manual wheelchair: Dark Skin Tone", []string{"person_in_manual_wheelchair_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f9bd", "person in manual wheelchair: Light Skin Tone", []string{"person_in_manual_wheelchair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9bd", "person in manual wheelchair: Medium-Light Skin Tone", []string{"person_in_manual_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9bd", "person in manual wheelchair: Medium Skin Tone", []string{"person_in_manual_wheelchair_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fe\u200d\U0001f9bd", "person in manual wheelchair: Medium-Dark Skin Tone", []string{"person_in_manual_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\U0001f9bd", "person in manual wheelchair: Dark Skin Tone", []string{"person_in_manual_wheelchair_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fe\u200d\U0001f9bc", "person in motorized wheelchair: Medium-Dark Skin Tone", []string{"person_in_motorized_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f9bc", "person in motorized wheelchair: Dark Skin Tone", []string{"person_in_motorized_wheelchair_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f9bc", "person in motorized wheelchair: Light Skin Tone", []string{"person_in_motorized_wheelchair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9bc", "person in motorized wheelchair: Medium-Light Skin Tone", []string{"person_in_motorized_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9bc", "person in motorized wheelchair: Medium Skin Tone", []string{"person_in_motorized_wheelchair_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fe\u200d\U0001f9bc", "person in motorized wheelchair: Medium-Dark Skin Tone", []string{"person_in_motorized_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f935\U0001f3fb", "person in tuxedo: Light Skin Tone", []string{"person_in_tuxedo_Light_Skin_Tone"}, "12.0", false}, {"\U0001f935\U0001f3fc", "person in tuxedo: Medium-Light Skin Tone", []string{"person_in_tuxedo_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f935\U0001f3fd", "person in tuxedo: Medium Skin Tone", []string{"person_in_tuxedo_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f935\U0001f3fe", "person in tuxedo: Medium-Dark Skin Tone", []string{"person_in_tuxedo_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f935\U0001f3ff", "person in tuxedo: Dark Skin Tone", []string{"person_in_tuxedo_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3ff\u200d\U0001f9b0", "person: red hair: Dark Skin Tone", []string{"person_red_hair_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f9b0", "person: red hair: Light Skin Tone", []string{"person_red_hair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9b0", "person: red hair: Medium-Light Skin Tone", []string{"person_red_hair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9b0", "person: red hair: Medium Skin Tone", []string{"person_red_hair_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f9b0", "person: red hair: Medium-Dark Skin Tone", []string{"person_red_hair_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3ff\u200d\U0001f9b0", "person: red hair: Dark Skin Tone", []string{"person_red_hair_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f9b0", "person: red hair: Light Skin Tone", []string{"person_red_hair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f9b3", "person: white hair: Light Skin Tone", []string{"person_white_hair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9b3", "person: white hair: Medium-Light Skin Tone", []string{"person_white_hair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9b3", "person: white hair: Medium Skin Tone", []string{"person_white_hair_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f9b3", "person: white hair: Medium-Dark Skin Tone", []string{"person_white_hair_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f9b3", "person: white hair: Dark Skin Tone", []string{"person_white_hair_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f9af", "person with white cane: Light Skin Tone", []string{"person_with_probing_cane_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f9af", "person with white cane: Medium-Light Skin Tone", []string{"person_with_probing_cane_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f9af", "person with white cane: Medium Skin Tone", []string{"person_with_probing_cane_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f9af", "person with white cane: Medium-Dark Skin Tone", []string{"person_with_probing_cane_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f9af", "person with white cane: Dark Skin Tone", []string{"person_with_probing_cane_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f9af", "person with white cane: Light Skin Tone", []string{"person_with_probing_cane_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3fe", "person wearing turban: Medium-Dark Skin Tone", []string{"person_with_turban_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3ff", "person wearing turban: Dark Skin Tone", []string{"person_with_turban_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fb", "person wearing turban: Light Skin Tone", []string{"person_with_turban_Light_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fc", "person wearing turban: Medium-Light Skin Tone", []string{"person_with_turban_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fd", "person wearing turban: Medium Skin Tone", []string{"person_with_turban_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3fe", "person wearing turban: Medium-Dark Skin Tone", []string{"person_with_turban_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3ff", "person wearing turban: Dark Skin Tone", []string{"person_with_turban_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f470\U0001f3fc", "person with veil: Medium-Light Skin Tone", []string{"person_with_veil_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f470\U0001f3fd", "person with veil: Medium Skin Tone", []string{"person_with_veil_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f470\U0001f3fe", "person with veil: Medium-Dark Skin Tone", []string{"person_with_veil_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f470\U0001f3ff", "person with veil: Dark Skin Tone", []string{"person_with_veil_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f470\U0001f3fb", "person with veil: Light Skin Tone", []string{"person_with_veil_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f470\U0001f3fc", "person with veil: Medium-Light Skin Tone", []string{"person_with_veil_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\u2708\ufe0f", "pilot: Light Skin Tone", []string{"pilot_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\u2708\ufe0f", "pilot: Medium-Light Skin Tone", []string{"pilot_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\u2708\ufe0f", "pilot: Medium Skin Tone", []string{"pilot_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\u2708\ufe0f", "pilot: Medium-Dark Skin Tone", []string{"pilot_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\u2708\ufe0f", "pilot: Dark Skin Tone", []string{"pilot_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f90f\U0001f3fd", "pinching hand: Medium Skin Tone", []string{"pinching_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f90f\U0001f3fe", "pinching hand: Medium-Dark Skin Tone", []string{"pinching_hand_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f90f\U0001f3ff", "pinching hand: Dark Skin Tone", []string{"pinching_hand_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f90f\U0001f3fb", "pinching hand: Light Skin Tone", []string{"pinching_hand_Light_Skin_Tone"}, "12.0", false}, {"\U0001f90f\U0001f3fc", "pinching hand: Medium-Light Skin Tone", []string{"pinching_hand_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f90f\U0001f3fd", "pinching hand: Medium Skin Tone", []string{"pinching_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f447\U0001f3ff", "backhand index pointing down: Dark Skin Tone", []string{"point_down_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f447\U0001f3fb", "backhand index pointing down: Light Skin Tone", []string{"point_down_Light_Skin_Tone"}, "12.0", false}, {"\U0001f447\U0001f3fc", "backhand index pointing down: Medium-Light Skin Tone", []string{"point_down_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f447\U0001f3fd", "backhand index pointing down: Medium Skin Tone", []string{"point_down_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f447\U0001f3fe", "backhand index pointing down: Medium-Dark Skin Tone", []string{"point_down_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f448\U0001f3fe", "backhand index pointing left: Medium-Dark Skin Tone", []string{"point_left_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f448\U0001f3ff", "backhand index pointing left: Dark Skin Tone", []string{"point_left_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f448\U0001f3fb", "backhand index pointing left: Light Skin Tone", []string{"point_left_Light_Skin_Tone"}, "12.0", false}, {"\U0001f448\U0001f3fc", "backhand index pointing left: Medium-Light Skin Tone", []string{"point_left_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f448\U0001f3fd", "backhand index pointing left: Medium Skin Tone", []string{"point_left_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f448\U0001f3fe", "backhand index pointing left: Medium-Dark Skin Tone", []string{"point_left_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f448\U0001f3ff", "backhand index pointing left: Dark Skin Tone", []string{"point_left_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f449\U0001f3fb", "backhand index pointing right: Light Skin Tone", []string{"point_right_Light_Skin_Tone"}, "12.0", false}, {"\U0001f449\U0001f3fc", "backhand index pointing right: Medium-Light Skin Tone", []string{"point_right_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f449\U0001f3fd", "backhand index pointing right: Medium Skin Tone", []string{"point_right_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f449\U0001f3fe", "backhand index pointing right: Medium-Dark Skin Tone", []string{"point_right_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f449\U0001f3ff", "backhand index pointing right: Dark Skin Tone", []string{"point_right_Dark_Skin_Tone"}, "12.0", false}, - {"\u261d\U0001f3fb\ufe0f", "index pointing up: Light Skin Tone", []string{"point_up_Light_Skin_Tone"}, "12.0", false}, {"\u261d\U0001f3fc\ufe0f", "index pointing up: Medium-Light Skin Tone", []string{"point_up_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u261d\U0001f3fd\ufe0f", "index pointing up: Medium Skin Tone", []string{"point_up_Medium_Skin_Tone"}, "12.0", false}, {"\u261d\U0001f3fe\ufe0f", "index pointing up: Medium-Dark Skin Tone", []string{"point_up_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\u261d\U0001f3ff\ufe0f", "index pointing up: Dark Skin Tone", []string{"point_up_Dark_Skin_Tone"}, "12.0", false}, + {"\u261d\U0001f3fb\ufe0f", "index pointing up: Light Skin Tone", []string{"point_up_Light_Skin_Tone"}, "12.0", false}, {"\U0001f446\U0001f3fb", "backhand index pointing up: Light Skin Tone", []string{"point_up_2_Light_Skin_Tone"}, "12.0", false}, {"\U0001f446\U0001f3fc", "backhand index pointing up: Medium-Light Skin Tone", []string{"point_up_2_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f446\U0001f3fd", "backhand index pointing up: Medium Skin Tone", []string{"point_up_2_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f446\U0001f3fe", "backhand index pointing up: Medium-Dark Skin Tone", []string{"point_up_2_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f446\U0001f3ff", "backhand index pointing up: Dark Skin Tone", []string{"point_up_2_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f46e\U0001f3ff", "police officer: Dark Skin Tone", []string{"police_officer_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fb", "police officer: Light Skin Tone", []string{"police_officer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fc", "police officer: Medium-Light Skin Tone", []string{"police_officer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fd", "police officer: Medium Skin Tone", []string{"police_officer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fe", "police officer: Medium-Dark Skin Tone", []string{"police_officer_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f46e\U0001f3ff", "police officer: Dark Skin Tone", []string{"police_officer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f46e\U0001f3fb\u200d\u2642\ufe0f", "man police officer: Light Skin Tone", []string{"policeman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f46e\U0001f3fc\u200d\u2642\ufe0f", "man police officer: Medium-Light Skin Tone", []string{"policeman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fd\u200d\u2642\ufe0f", "man police officer: Medium Skin Tone", []string{"policeman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fe\u200d\u2642\ufe0f", "man police officer: Medium-Dark Skin Tone", []string{"policeman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3ff\u200d\u2642\ufe0f", "man police officer: Dark Skin Tone", []string{"policeman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f46e\U0001f3fb\u200d\u2640\ufe0f", "woman police officer: Light Skin Tone", []string{"policewoman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f46e\U0001f3fc\u200d\u2640\ufe0f", "woman police officer: Medium-Light Skin Tone", []string{"policewoman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f46e\U0001f3fb\u200d\u2642\ufe0f", "man police officer: Light Skin Tone", []string{"policeman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f46e\U0001f3fc\u200d\u2642\ufe0f", "man police officer: Medium-Light Skin Tone", []string{"policeman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fd\u200d\u2640\ufe0f", "woman police officer: Medium Skin Tone", []string{"policewoman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3fe\u200d\u2640\ufe0f", "woman police officer: Medium-Dark Skin Tone", []string{"policewoman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f46e\U0001f3ff\u200d\u2640\ufe0f", "woman police officer: Dark Skin Tone", []string{"policewoman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f46e\U0001f3fb\u200d\u2640\ufe0f", "woman police officer: Light Skin Tone", []string{"policewoman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f46e\U0001f3fc\u200d\u2640\ufe0f", "woman police officer: Medium-Light Skin Tone", []string{"policewoman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64e\U0001f3fb", "person pouting: Light Skin Tone", []string{"pouting_face_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fc", "person pouting: Medium-Light Skin Tone", []string{"pouting_face_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fd", "person pouting: Medium Skin Tone", []string{"pouting_face_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fe", "person pouting: Medium-Dark Skin Tone", []string{"pouting_face_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3ff", "person pouting: Dark Skin Tone", []string{"pouting_face_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64e\U0001f3fb", "person pouting: Light Skin Tone", []string{"pouting_face_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64e\U0001f3fe\u200d\u2642\ufe0f", "man pouting: Medium-Dark Skin Tone", []string{"pouting_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f64e\U0001f3ff\u200d\u2642\ufe0f", "man pouting: Dark Skin Tone", []string{"pouting_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fb\u200d\u2642\ufe0f", "man pouting: Light Skin Tone", []string{"pouting_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fc\u200d\u2642\ufe0f", "man pouting: Medium-Light Skin Tone", []string{"pouting_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fd\u200d\u2642\ufe0f", "man pouting: Medium Skin Tone", []string{"pouting_man_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f64e\U0001f3fe\u200d\u2642\ufe0f", "man pouting: Medium-Dark Skin Tone", []string{"pouting_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64e\U0001f3ff\u200d\u2642\ufe0f", "man pouting: Dark Skin Tone", []string{"pouting_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f64e\U0001f3fb\u200d\u2640\ufe0f", "woman pouting: Light Skin Tone", []string{"pouting_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64e\U0001f3fc\u200d\u2640\ufe0f", "woman pouting: Medium-Light Skin Tone", []string{"pouting_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fd\u200d\u2640\ufe0f", "woman pouting: Medium Skin Tone", []string{"pouting_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3fe\u200d\u2640\ufe0f", "woman pouting: Medium-Dark Skin Tone", []string{"pouting_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64e\U0001f3ff\u200d\u2640\ufe0f", "woman pouting: Dark Skin Tone", []string{"pouting_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64e\U0001f3fb\u200d\u2640\ufe0f", "woman pouting: Light Skin Tone", []string{"pouting_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f64e\U0001f3fc\u200d\u2640\ufe0f", "woman pouting: Medium-Light Skin Tone", []string{"pouting_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64f\U0001f3fb", "folded hands: Light Skin Tone", []string{"pray_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64f\U0001f3fc", "folded hands: Medium-Light Skin Tone", []string{"pray_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64f\U0001f3fd", "folded hands: Medium Skin Tone", []string{"pray_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64f\U0001f3fe", "folded hands: Medium-Dark Skin Tone", []string{"pray_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64f\U0001f3ff", "folded hands: Dark Skin Tone", []string{"pray_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f930\U0001f3fb", "pregnant woman: Light Skin Tone", []string{"pregnant_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f930\U0001f3fc", "pregnant woman: Medium-Light Skin Tone", []string{"pregnant_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f930\U0001f3fd", "pregnant woman: Medium Skin Tone", []string{"pregnant_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f930\U0001f3fe", "pregnant woman: Medium-Dark Skin Tone", []string{"pregnant_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f930\U0001f3ff", "pregnant woman: Dark Skin Tone", []string{"pregnant_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f930\U0001f3fb", "pregnant woman: Light Skin Tone", []string{"pregnant_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f930\U0001f3fc", "pregnant woman: Medium-Light Skin Tone", []string{"pregnant_woman_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f934\U0001f3fe", "prince: Medium-Dark Skin Tone", []string{"prince_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f934\U0001f3ff", "prince: Dark Skin Tone", []string{"prince_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f934\U0001f3fb", "prince: Light Skin Tone", []string{"prince_Light_Skin_Tone"}, "12.0", false}, {"\U0001f934\U0001f3fc", "prince: Medium-Light Skin Tone", []string{"prince_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f934\U0001f3fd", "prince: Medium Skin Tone", []string{"prince_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f478\U0001f3fb", "princess: Light Skin Tone", []string{"princess_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f934\U0001f3fe", "prince: Medium-Dark Skin Tone", []string{"prince_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f478\U0001f3fc", "princess: Medium-Light Skin Tone", []string{"princess_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f478\U0001f3fd", "princess: Medium Skin Tone", []string{"princess_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f478\U0001f3fe", "princess: Medium-Dark Skin Tone", []string{"princess_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f478\U0001f3ff", "princess: Dark Skin Tone", []string{"princess_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f478\U0001f3fb", "princess: Light Skin Tone", []string{"princess_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f91a\U0001f3ff", "raised back of hand: Dark Skin Tone", []string{"raised_back_of_hand_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f91a\U0001f3fb", "raised back of hand: Light Skin Tone", []string{"raised_back_of_hand_Light_Skin_Tone"}, "12.0", false}, {"\U0001f91a\U0001f3fc", "raised back of hand: Medium-Light Skin Tone", []string{"raised_back_of_hand_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f91a\U0001f3fd", "raised back of hand: Medium Skin Tone", []string{"raised_back_of_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f91a\U0001f3fe", "raised back of hand: Medium-Dark Skin Tone", []string{"raised_back_of_hand_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f91a\U0001f3ff", "raised back of hand: Dark Skin Tone", []string{"raised_back_of_hand_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f590\U0001f3fd\ufe0f", "hand with fingers splayed: Medium Skin Tone", []string{"raised_hand_with_fingers_splayed_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f590\U0001f3fe\ufe0f", "hand with fingers splayed: Medium-Dark Skin Tone", []string{"raised_hand_with_fingers_splayed_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f590\U0001f3ff\ufe0f", "hand with fingers splayed: Dark Skin Tone", []string{"raised_hand_with_fingers_splayed_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f590\U0001f3fb\ufe0f", "hand with fingers splayed: Light Skin Tone", []string{"raised_hand_with_fingers_splayed_Light_Skin_Tone"}, "12.0", false}, {"\U0001f590\U0001f3fc\ufe0f", "hand with fingers splayed: Medium-Light Skin Tone", []string{"raised_hand_with_fingers_splayed_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f590\U0001f3fd\ufe0f", "hand with fingers splayed: Medium Skin Tone", []string{"raised_hand_with_fingers_splayed_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64c\U0001f3fb", "raising hands: Light Skin Tone", []string{"raised_hands_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64c\U0001f3fc", "raising hands: Medium-Light Skin Tone", []string{"raised_hands_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64c\U0001f3fd", "raising hands: Medium Skin Tone", []string{"raised_hands_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64c\U0001f3fe", "raising hands: Medium-Dark Skin Tone", []string{"raised_hands_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64c\U0001f3ff", "raising hands: Dark Skin Tone", []string{"raised_hands_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f64b\U0001f3ff", "person raising hand: Dark Skin Tone", []string{"raising_hand_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f64b\U0001f3fb", "person raising hand: Light Skin Tone", []string{"raising_hand_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fc", "person raising hand: Medium-Light Skin Tone", []string{"raising_hand_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fd", "person raising hand: Medium Skin Tone", []string{"raising_hand_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fe", "person raising hand: Medium-Dark Skin Tone", []string{"raising_hand_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64b\U0001f3ff", "person raising hand: Dark Skin Tone", []string{"raising_hand_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64b\U0001f3fb", "person raising hand: Light Skin Tone", []string{"raising_hand_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3ff\u200d\u2642\ufe0f", "man raising hand: Dark Skin Tone", []string{"raising_hand_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fb\u200d\u2642\ufe0f", "man raising hand: Light Skin Tone", []string{"raising_hand_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fc\u200d\u2642\ufe0f", "man raising hand: Medium-Light Skin Tone", []string{"raising_hand_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fd\u200d\u2642\ufe0f", "man raising hand: Medium Skin Tone", []string{"raising_hand_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fe\u200d\u2642\ufe0f", "man raising hand: Medium-Dark Skin Tone", []string{"raising_hand_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64b\U0001f3fe\u200d\u2640\ufe0f", "woman raising hand: Medium-Dark Skin Tone", []string{"raising_hand_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f64b\U0001f3ff\u200d\u2640\ufe0f", "woman raising hand: Dark Skin Tone", []string{"raising_hand_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fb\u200d\u2640\ufe0f", "woman raising hand: Light Skin Tone", []string{"raising_hand_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fc\u200d\u2640\ufe0f", "woman raising hand: Medium-Light Skin Tone", []string{"raising_hand_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f64b\U0001f3fd\u200d\u2640\ufe0f", "woman raising hand: Medium Skin Tone", []string{"raising_hand_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fc\u200d\U0001f9b0", "man: red hair: Medium-Light Skin Tone", []string{"red_haired_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f64b\U0001f3fe\u200d\u2640\ufe0f", "woman raising hand: Medium-Dark Skin Tone", []string{"raising_hand_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f64b\U0001f3ff\u200d\u2640\ufe0f", "woman raising hand: Dark Skin Tone", []string{"raising_hand_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9b0", "man: red hair: Medium Skin Tone", []string{"red_haired_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f9b0", "man: red hair: Medium-Dark Skin Tone", []string{"red_haired_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f9b0", "man: red hair: Dark Skin Tone", []string{"red_haired_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fb\u200d\U0001f9b0", "man: red hair: Light Skin Tone", []string{"red_haired_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fc\u200d\U0001f9b0", "man: red hair: Medium-Light Skin Tone", []string{"red_haired_man_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\U0001f9b0", "woman: red hair: Medium-Dark Skin Tone", []string{"red_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f9b0", "woman: red hair: Dark Skin Tone", []string{"red_haired_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9b0", "woman: red hair: Light Skin Tone", []string{"red_haired_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9b0", "woman: red hair: Medium-Light Skin Tone", []string{"red_haired_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9b0", "woman: red hair: Medium Skin Tone", []string{"red_haired_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\U0001f9b0", "woman: red hair: Medium-Dark Skin Tone", []string{"red_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f9b0", "woman: red hair: Dark Skin Tone", []string{"red_haired_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fb", "person rowing boat: Light Skin Tone", []string{"rowboat_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fc", "person rowing boat: Medium-Light Skin Tone", []string{"rowboat_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fd", "person rowing boat: Medium Skin Tone", []string{"rowboat_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fe", "person rowing boat: Medium-Dark Skin Tone", []string{"rowboat_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3ff", "person rowing boat: Dark Skin Tone", []string{"rowboat_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6a3\U0001f3ff\u200d\u2642\ufe0f", "man rowing boat: Dark Skin Tone", []string{"rowing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fb\u200d\u2642\ufe0f", "man rowing boat: Light Skin Tone", []string{"rowing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fc\u200d\u2642\ufe0f", "man rowing boat: Medium-Light Skin Tone", []string{"rowing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fd\u200d\u2642\ufe0f", "man rowing boat: Medium Skin Tone", []string{"rowing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fe\u200d\u2642\ufe0f", "man rowing boat: Medium-Dark Skin Tone", []string{"rowing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6a3\U0001f3ff\u200d\u2642\ufe0f", "man rowing boat: Dark Skin Tone", []string{"rowing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fb\u200d\u2640\ufe0f", "woman rowing boat: Light Skin Tone", []string{"rowing_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fc\u200d\u2640\ufe0f", "woman rowing boat: Medium-Light Skin Tone", []string{"rowing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6a3\U0001f3fd\u200d\u2640\ufe0f", "woman rowing boat: Medium Skin Tone", []string{"rowing_woman_Medium_Skin_Tone"}, "12.0", false}, @@ -2711,41 +2750,41 @@ var GemojiData = Gemoji{ {"\U0001f3c3\U0001f3fd\u200d\u2642\ufe0f", "man running: Medium Skin Tone", []string{"running_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3fe\u200d\u2642\ufe0f", "man running: Medium-Dark Skin Tone", []string{"running_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3ff\u200d\u2642\ufe0f", "man running: Dark Skin Tone", []string{"running_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f3c3\U0001f3ff\u200d\u2640\ufe0f", "woman running: Dark Skin Tone", []string{"running_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3fb\u200d\u2640\ufe0f", "woman running: Light Skin Tone", []string{"running_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3fc\u200d\u2640\ufe0f", "woman running: Medium-Light Skin Tone", []string{"running_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3fd\u200d\u2640\ufe0f", "woman running: Medium Skin Tone", []string{"running_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c3\U0001f3fe\u200d\u2640\ufe0f", "woman running: Medium-Dark Skin Tone", []string{"running_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3c3\U0001f3ff\u200d\u2640\ufe0f", "woman running: Dark Skin Tone", []string{"running_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f385\U0001f3fb", "Santa Claus: Light Skin Tone", []string{"santa_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f385\U0001f3fc", "Santa Claus: Medium-Light Skin Tone", []string{"santa_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f385\U0001f3fd", "Santa Claus: Medium Skin Tone", []string{"santa_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f385\U0001f3fe", "Santa Claus: Medium-Dark Skin Tone", []string{"santa_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f385\U0001f3ff", "Santa Claus: Dark Skin Tone", []string{"santa_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f385\U0001f3fb", "Santa Claus: Light Skin Tone", []string{"santa_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f385\U0001f3fc", "Santa Claus: Medium-Light Skin Tone", []string{"santa_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fb\u200d\u2642\ufe0f", "man in steamy room: Light Skin Tone", []string{"sauna_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fc\u200d\u2642\ufe0f", "man in steamy room: Medium-Light Skin Tone", []string{"sauna_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fd\u200d\u2642\ufe0f", "man in steamy room: Medium Skin Tone", []string{"sauna_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fe\u200d\u2642\ufe0f", "man in steamy room: Medium-Dark Skin Tone", []string{"sauna_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3ff\u200d\u2642\ufe0f", "man in steamy room: Dark Skin Tone", []string{"sauna_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d6\U0001f3ff", "person in steamy room: Dark Skin Tone", []string{"sauna_person_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fb", "person in steamy room: Light Skin Tone", []string{"sauna_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fc", "person in steamy room: Medium-Light Skin Tone", []string{"sauna_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fd", "person in steamy room: Medium Skin Tone", []string{"sauna_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fe", "person in steamy room: Medium-Dark Skin Tone", []string{"sauna_person_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d6\U0001f3ff", "person in steamy room: Dark Skin Tone", []string{"sauna_person_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", "woman in steamy room: Light Skin Tone", []string{"sauna_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fc\u200d\u2640\ufe0f", "woman in steamy room: Medium-Light Skin Tone", []string{"sauna_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fd\u200d\u2640\ufe0f", "woman in steamy room: Medium Skin Tone", []string{"sauna_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3fe\u200d\u2640\ufe0f", "woman in steamy room: Medium-Dark Skin Tone", []string{"sauna_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d6\U0001f3ff\u200d\u2640\ufe0f", "woman in steamy room: Dark Skin Tone", []string{"sauna_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d6\U0001f3fb\u200d\u2640\ufe0f", "woman in steamy room: Light Skin Tone", []string{"sauna_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f52c", "scientist: Light Skin Tone", []string{"scientist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f52c", "scientist: Medium-Light Skin Tone", []string{"scientist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f52c", "scientist: Medium Skin Tone", []string{"scientist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f52c", "scientist: Medium-Dark Skin Tone", []string{"scientist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f52c", "scientist: Dark Skin Tone", []string{"scientist_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f52c", "scientist: Light Skin Tone", []string{"scientist_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f933\U0001f3fb", "selfie: Light Skin Tone", []string{"selfie_Light_Skin_Tone"}, "12.0", false}, {"\U0001f933\U0001f3fc", "selfie: Medium-Light Skin Tone", []string{"selfie_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f933\U0001f3fd", "selfie: Medium Skin Tone", []string{"selfie_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f933\U0001f3fe", "selfie: Medium-Dark Skin Tone", []string{"selfie_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f933\U0001f3ff", "selfie: Dark Skin Tone", []string{"selfie_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f933\U0001f3fb", "selfie: Light Skin Tone", []string{"selfie_Light_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fe", "person shrugging: Medium-Dark Skin Tone", []string{"shrug_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3ff", "person shrugging: Dark Skin Tone", []string{"shrug_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fb", "person shrugging: Light Skin Tone", []string{"shrug_Light_Skin_Tone"}, "12.0", false}, @@ -2756,36 +2795,36 @@ var GemojiData = Gemoji{ {"\U0001f9d1\U0001f3fd\u200d\U0001f3a4", "singer: Medium Skin Tone", []string{"singer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f3a4", "singer: Medium-Dark Skin Tone", []string{"singer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f3a4", "singer: Dark Skin Tone", []string{"singer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6cc\U0001f3fc", "person in bed: Medium-Light Skin Tone", []string{"sleeping_bed_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6cc\U0001f3fd", "person in bed: Medium Skin Tone", []string{"sleeping_bed_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6cc\U0001f3fe", "person in bed: Medium-Dark Skin Tone", []string{"sleeping_bed_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6cc\U0001f3ff", "person in bed: Dark Skin Tone", []string{"sleeping_bed_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6cc\U0001f3fb", "person in bed: Light Skin Tone", []string{"sleeping_bed_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f6cc\U0001f3fc", "person in bed: Medium-Light Skin Tone", []string{"sleeping_bed_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3c2\U0001f3fe", "snowboarder: Medium-Dark Skin Tone", []string{"snowboarder_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c2\U0001f3ff", "snowboarder: Dark Skin Tone", []string{"snowboarder_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c2\U0001f3fb", "snowboarder: Light Skin Tone", []string{"snowboarder_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c2\U0001f3fc", "snowboarder: Medium-Light Skin Tone", []string{"snowboarder_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c2\U0001f3fd", "snowboarder: Medium Skin Tone", []string{"snowboarder_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f3c2\U0001f3fe", "snowboarder: Medium-Dark Skin Tone", []string{"snowboarder_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9cd\U0001f3ff\u200d\u2642\ufe0f", "man standing: Dark Skin Tone", []string{"standing_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fb\u200d\u2642\ufe0f", "man standing: Light Skin Tone", []string{"standing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fc\u200d\u2642\ufe0f", "man standing: Medium-Light Skin Tone", []string{"standing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fd\u200d\u2642\ufe0f", "man standing: Medium Skin Tone", []string{"standing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fe\u200d\u2642\ufe0f", "man standing: Medium-Dark Skin Tone", []string{"standing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cd\U0001f3ff\u200d\u2642\ufe0f", "man standing: Dark Skin Tone", []string{"standing_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9cd\U0001f3fb", "person standing: Light Skin Tone", []string{"standing_person_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9cd\U0001f3fc", "person standing: Medium-Light Skin Tone", []string{"standing_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fd", "person standing: Medium Skin Tone", []string{"standing_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fe", "person standing: Medium-Dark Skin Tone", []string{"standing_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3ff", "person standing: Dark Skin Tone", []string{"standing_person_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cd\U0001f3fb", "person standing: Light Skin Tone", []string{"standing_person_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9cd\U0001f3fc", "person standing: Medium-Light Skin Tone", []string{"standing_person_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9cd\U0001f3ff\u200d\u2640\ufe0f", "woman standing: Dark Skin Tone", []string{"standing_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fb\u200d\u2640\ufe0f", "woman standing: Light Skin Tone", []string{"standing_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fc\u200d\u2640\ufe0f", "woman standing: Medium-Light Skin Tone", []string{"standing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fd\u200d\u2640\ufe0f", "woman standing: Medium Skin Tone", []string{"standing_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9cd\U0001f3fe\u200d\u2640\ufe0f", "woman standing: Medium-Dark Skin Tone", []string{"standing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9cd\U0001f3ff\u200d\u2640\ufe0f", "woman standing: Dark Skin Tone", []string{"standing_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f393", "student: Light Skin Tone", []string{"student_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fc\u200d\U0001f393", "student: Medium-Light Skin Tone", []string{"student_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f393", "student: Medium Skin Tone", []string{"student_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f393", "student: Medium-Dark Skin Tone", []string{"student_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f393", "student: Dark Skin Tone", []string{"student_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f393", "student: Light Skin Tone", []string{"student_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fc\u200d\U0001f393", "student: Medium-Light Skin Tone", []string{"student_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fb", "superhero: Light Skin Tone", []string{"superhero_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fc", "superhero: Medium-Light Skin Tone", []string{"superhero_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fd", "superhero: Medium Skin Tone", []string{"superhero_Medium_Skin_Tone"}, "12.0", false}, @@ -2796,81 +2835,81 @@ var GemojiData = Gemoji{ {"\U0001f9b8\U0001f3fd\u200d\u2642\ufe0f", "man superhero: Medium Skin Tone", []string{"superhero_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fe\u200d\u2642\ufe0f", "man superhero: Medium-Dark Skin Tone", []string{"superhero_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3ff\u200d\u2642\ufe0f", "man superhero: Dark Skin Tone", []string{"superhero_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9b8\U0001f3ff\u200d\u2640\ufe0f", "woman superhero: Dark Skin Tone", []string{"superhero_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fb\u200d\u2640\ufe0f", "woman superhero: Light Skin Tone", []string{"superhero_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fc\u200d\u2640\ufe0f", "woman superhero: Medium-Light Skin Tone", []string{"superhero_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fd\u200d\u2640\ufe0f", "woman superhero: Medium Skin Tone", []string{"superhero_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b8\U0001f3fe\u200d\u2640\ufe0f", "woman superhero: Medium-Dark Skin Tone", []string{"superhero_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9b8\U0001f3ff\u200d\u2640\ufe0f", "woman superhero: Dark Skin Tone", []string{"superhero_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fe", "supervillain: Medium-Dark Skin Tone", []string{"supervillain_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3ff", "supervillain: Dark Skin Tone", []string{"supervillain_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fb", "supervillain: Light Skin Tone", []string{"supervillain_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fc", "supervillain: Medium-Light Skin Tone", []string{"supervillain_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fd", "supervillain: Medium Skin Tone", []string{"supervillain_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f9b9\U0001f3ff\u200d\u2642\ufe0f", "man supervillain: Dark Skin Tone", []string{"supervillain_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fb\u200d\u2642\ufe0f", "man supervillain: Light Skin Tone", []string{"supervillain_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fc\u200d\u2642\ufe0f", "man supervillain: Medium-Light Skin Tone", []string{"supervillain_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fd\u200d\u2642\ufe0f", "man supervillain: Medium Skin Tone", []string{"supervillain_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fe\u200d\u2642\ufe0f", "man supervillain: Medium-Dark Skin Tone", []string{"supervillain_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9b9\U0001f3ff\u200d\u2642\ufe0f", "man supervillain: Dark Skin Tone", []string{"supervillain_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9b9\U0001f3fb\u200d\u2640\ufe0f", "woman supervillain: Light Skin Tone", []string{"supervillain_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9b9\U0001f3fc\u200d\u2640\ufe0f", "woman supervillain: Medium-Light Skin Tone", []string{"supervillain_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fd\u200d\u2640\ufe0f", "woman supervillain: Medium Skin Tone", []string{"supervillain_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3fe\u200d\u2640\ufe0f", "woman supervillain: Medium-Dark Skin Tone", []string{"supervillain_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9b9\U0001f3ff\u200d\u2640\ufe0f", "woman supervillain: Dark Skin Tone", []string{"supervillain_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9b9\U0001f3fb\u200d\u2640\ufe0f", "woman supervillain: Light Skin Tone", []string{"supervillain_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9b9\U0001f3fc\u200d\u2640\ufe0f", "woman supervillain: Medium-Light Skin Tone", []string{"supervillain_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3c4\U0001f3fb", "person surfing: Light Skin Tone", []string{"surfer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fc", "person surfing: Medium-Light Skin Tone", []string{"surfer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fd", "person surfing: Medium Skin Tone", []string{"surfer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fe", "person surfing: Medium-Dark Skin Tone", []string{"surfer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3ff", "person surfing: Dark Skin Tone", []string{"surfer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3c4\U0001f3fb", "person surfing: Light Skin Tone", []string{"surfer_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f3c4\U0001f3fb\u200d\u2642\ufe0f", "man surfing: Light Skin Tone", []string{"surfing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fc\u200d\u2642\ufe0f", "man surfing: Medium-Light Skin Tone", []string{"surfing_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fd\u200d\u2642\ufe0f", "man surfing: Medium Skin Tone", []string{"surfing_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fe\u200d\u2642\ufe0f", "man surfing: Medium-Dark Skin Tone", []string{"surfing_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3ff\u200d\u2642\ufe0f", "man surfing: Dark Skin Tone", []string{"surfing_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f3c4\U0001f3fb\u200d\u2642\ufe0f", "man surfing: Light Skin Tone", []string{"surfing_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fb\u200d\u2640\ufe0f", "woman surfing: Light Skin Tone", []string{"surfing_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fc\u200d\u2640\ufe0f", "woman surfing: Medium-Light Skin Tone", []string{"surfing_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fd\u200d\u2640\ufe0f", "woman surfing: Medium Skin Tone", []string{"surfing_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3fe\u200d\u2640\ufe0f", "woman surfing: Medium-Dark Skin Tone", []string{"surfing_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3c4\U0001f3ff\u200d\u2640\ufe0f", "woman surfing: Dark Skin Tone", []string{"surfing_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3ca\U0001f3ff", "person swimming: Dark Skin Tone", []string{"swimmer_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fb", "person swimming: Light Skin Tone", []string{"swimmer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fc", "person swimming: Medium-Light Skin Tone", []string{"swimmer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fd", "person swimming: Medium Skin Tone", []string{"swimmer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fe", "person swimming: Medium-Dark Skin Tone", []string{"swimmer_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f3ca\U0001f3ff", "person swimming: Dark Skin Tone", []string{"swimmer_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fb\u200d\u2642\ufe0f", "man swimming: Light Skin Tone", []string{"swimming_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fc\u200d\u2642\ufe0f", "man swimming: Medium-Light Skin Tone", []string{"swimming_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fd\u200d\u2642\ufe0f", "man swimming: Medium Skin Tone", []string{"swimming_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fe\u200d\u2642\ufe0f", "man swimming: Medium-Dark Skin Tone", []string{"swimming_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3ff\u200d\u2642\ufe0f", "man swimming: Dark Skin Tone", []string{"swimming_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3ca\U0001f3fc\u200d\u2640\ufe0f", "woman swimming: Medium-Light Skin Tone", []string{"swimming_woman_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f3ca\U0001f3fd\u200d\u2640\ufe0f", "woman swimming: Medium Skin Tone", []string{"swimming_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fe\u200d\u2640\ufe0f", "woman swimming: Medium-Dark Skin Tone", []string{"swimming_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3ff\u200d\u2640\ufe0f", "woman swimming: Dark Skin Tone", []string{"swimming_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3ca\U0001f3fb\u200d\u2640\ufe0f", "woman swimming: Light Skin Tone", []string{"swimming_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3ca\U0001f3fc\u200d\u2640\ufe0f", "woman swimming: Medium-Light Skin Tone", []string{"swimming_woman_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3ca\U0001f3fd\u200d\u2640\ufe0f", "woman swimming: Medium Skin Tone", []string{"swimming_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d1\U0001f3fb\u200d\U0001f3eb", "teacher: Light Skin Tone", []string{"teacher_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f3eb", "teacher: Medium-Light Skin Tone", []string{"teacher_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f3eb", "teacher: Medium Skin Tone", []string{"teacher_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f3eb", "teacher: Medium-Dark Skin Tone", []string{"teacher_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f3eb", "teacher: Dark Skin Tone", []string{"teacher_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d1\U0001f3fb\u200d\U0001f3eb", "teacher: Light Skin Tone", []string{"teacher_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fb\u200d\U0001f4bb", "technologist: Light Skin Tone", []string{"technologist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fc\u200d\U0001f4bb", "technologist: Medium-Light Skin Tone", []string{"technologist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fd\u200d\U0001f4bb", "technologist: Medium Skin Tone", []string{"technologist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3fe\u200d\U0001f4bb", "technologist: Medium-Dark Skin Tone", []string{"technologist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d1\U0001f3ff\u200d\U0001f4bb", "technologist: Dark Skin Tone", []string{"technologist_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f481\U0001f3ff\u200d\u2642\ufe0f", "man tipping hand: Dark Skin Tone", []string{"tipping_hand_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fb\u200d\u2642\ufe0f", "man tipping hand: Light Skin Tone", []string{"tipping_hand_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fc\u200d\u2642\ufe0f", "man tipping hand: Medium-Light Skin Tone", []string{"tipping_hand_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fd\u200d\u2642\ufe0f", "man tipping hand: Medium Skin Tone", []string{"tipping_hand_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fe\u200d\u2642\ufe0f", "man tipping hand: Medium-Dark Skin Tone", []string{"tipping_hand_man_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f481\U0001f3ff\u200d\u2642\ufe0f", "man tipping hand: Dark Skin Tone", []string{"tipping_hand_man_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fb", "person tipping hand: Light Skin Tone", []string{"tipping_hand_person_Light_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fc", "person tipping hand: Medium-Light Skin Tone", []string{"tipping_hand_person_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fd", "person tipping hand: Medium Skin Tone", []string{"tipping_hand_person_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fe", "person tipping hand: Medium-Dark Skin Tone", []string{"tipping_hand_person_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3ff", "person tipping hand: Dark Skin Tone", []string{"tipping_hand_person_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f481\U0001f3fb\u200d\u2640\ufe0f", "woman tipping hand: Light Skin Tone", []string{"tipping_hand_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f481\U0001f3fc\u200d\u2640\ufe0f", "woman tipping hand: Medium-Light Skin Tone", []string{"tipping_hand_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fd\u200d\u2640\ufe0f", "woman tipping hand: Medium Skin Tone", []string{"tipping_hand_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3fe\u200d\u2640\ufe0f", "woman tipping hand: Medium-Dark Skin Tone", []string{"tipping_hand_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f481\U0001f3ff\u200d\u2640\ufe0f", "woman tipping hand: Dark Skin Tone", []string{"tipping_hand_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f481\U0001f3fb\u200d\u2640\ufe0f", "woman tipping hand: Light Skin Tone", []string{"tipping_hand_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f481\U0001f3fc\u200d\u2640\ufe0f", "woman tipping hand: Medium-Light Skin Tone", []string{"tipping_hand_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46c\U0001f3fb", "men holding hands: Light Skin Tone", []string{"two_men_holding_hands_Light_Skin_Tone"}, "12.0", false}, {"\U0001f46c\U0001f3fc", "men holding hands: Medium-Light Skin Tone", []string{"two_men_holding_hands_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f46c\U0001f3fd", "men holding hands: Medium Skin Tone", []string{"two_men_holding_hands_Medium_Skin_Tone"}, "12.0", false}, @@ -2886,21 +2925,21 @@ var GemojiData = Gemoji{ {"\u270c\U0001f3fd\ufe0f", "victory hand: Medium Skin Tone", []string{"v_Medium_Skin_Tone"}, "12.0", false}, {"\u270c\U0001f3fe\ufe0f", "victory hand: Medium-Dark Skin Tone", []string{"v_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\u270c\U0001f3ff\ufe0f", "victory hand: Dark Skin Tone", []string{"v_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9db\U0001f3fb", "vampire: Light Skin Tone", []string{"vampire_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9db\U0001f3fc", "vampire: Medium-Light Skin Tone", []string{"vampire_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fd", "vampire: Medium Skin Tone", []string{"vampire_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fe", "vampire: Medium-Dark Skin Tone", []string{"vampire_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3ff", "vampire: Dark Skin Tone", []string{"vampire_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9db\U0001f3fb", "vampire: Light Skin Tone", []string{"vampire_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9db\U0001f3fc", "vampire: Medium-Light Skin Tone", []string{"vampire_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fb\u200d\u2642\ufe0f", "man vampire: Light Skin Tone", []string{"vampire_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fc\u200d\u2642\ufe0f", "man vampire: Medium-Light Skin Tone", []string{"vampire_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fd\u200d\u2642\ufe0f", "man vampire: Medium Skin Tone", []string{"vampire_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fe\u200d\u2642\ufe0f", "man vampire: Medium-Dark Skin Tone", []string{"vampire_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3ff\u200d\u2642\ufe0f", "man vampire: Dark Skin Tone", []string{"vampire_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f9db\U0001f3fb\u200d\u2640\ufe0f", "woman vampire: Light Skin Tone", []string{"vampire_woman_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f9db\U0001f3fc\u200d\u2640\ufe0f", "woman vampire: Medium-Light Skin Tone", []string{"vampire_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fd\u200d\u2640\ufe0f", "woman vampire: Medium Skin Tone", []string{"vampire_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3fe\u200d\u2640\ufe0f", "woman vampire: Medium-Dark Skin Tone", []string{"vampire_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9db\U0001f3ff\u200d\u2640\ufe0f", "woman vampire: Dark Skin Tone", []string{"vampire_woman_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9db\U0001f3fb\u200d\u2640\ufe0f", "woman vampire: Light Skin Tone", []string{"vampire_woman_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f9db\U0001f3fc\u200d\u2640\ufe0f", "woman vampire: Medium-Light Skin Tone", []string{"vampire_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f596\U0001f3fb", "vulcan salute: Light Skin Tone", []string{"vulcan_salute_Light_Skin_Tone"}, "12.0", false}, {"\U0001f596\U0001f3fc", "vulcan salute: Medium-Light Skin Tone", []string{"vulcan_salute_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f596\U0001f3fd", "vulcan salute: Medium Skin Tone", []string{"vulcan_salute_Medium_Skin_Tone"}, "12.0", false}, @@ -2911,26 +2950,26 @@ var GemojiData = Gemoji{ {"\U0001f6b6\U0001f3fd", "person walking: Medium Skin Tone", []string{"walking_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fe", "person walking: Medium-Dark Skin Tone", []string{"walking_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3ff", "person walking: Dark Skin Tone", []string{"walking_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6b6\U0001f3fb\u200d\u2642\ufe0f", "man walking: Light Skin Tone", []string{"walking_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fc\u200d\u2642\ufe0f", "man walking: Medium-Light Skin Tone", []string{"walking_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fd\u200d\u2642\ufe0f", "man walking: Medium Skin Tone", []string{"walking_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fe\u200d\u2642\ufe0f", "man walking: Medium-Dark Skin Tone", []string{"walking_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3ff\u200d\u2642\ufe0f", "man walking: Dark Skin Tone", []string{"walking_man_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6b6\U0001f3fb\u200d\u2642\ufe0f", "man walking: Light Skin Tone", []string{"walking_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f6b6\U0001f3fe\u200d\u2640\ufe0f", "woman walking: Medium-Dark Skin Tone", []string{"walking_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f6b6\U0001f3ff\u200d\u2640\ufe0f", "woman walking: Dark Skin Tone", []string{"walking_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fb\u200d\u2640\ufe0f", "woman walking: Light Skin Tone", []string{"walking_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fc\u200d\u2640\ufe0f", "woman walking: Medium-Light Skin Tone", []string{"walking_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f6b6\U0001f3fd\u200d\u2640\ufe0f", "woman walking: Medium Skin Tone", []string{"walking_woman_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f6b6\U0001f3fe\u200d\u2640\ufe0f", "woman walking: Medium-Dark Skin Tone", []string{"walking_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f6b6\U0001f3ff\u200d\u2640\ufe0f", "woman walking: Dark Skin Tone", []string{"walking_woman_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f93d\U0001f3fb", "person playing water polo: Light Skin Tone", []string{"water_polo_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f93d\U0001f3fc", "person playing water polo: Medium-Light Skin Tone", []string{"water_polo_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3fd", "person playing water polo: Medium Skin Tone", []string{"water_polo_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3fe", "person playing water polo: Medium-Dark Skin Tone", []string{"water_polo_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3ff", "person playing water polo: Dark Skin Tone", []string{"water_polo_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f93d\U0001f3fb", "person playing water polo: Light Skin Tone", []string{"water_polo_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f93d\U0001f3fc", "person playing water polo: Medium-Light Skin Tone", []string{"water_polo_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f44b\U0001f3ff", "waving hand: Dark Skin Tone", []string{"wave_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f44b\U0001f3fb", "waving hand: Light Skin Tone", []string{"wave_Light_Skin_Tone"}, "12.0", false}, {"\U0001f44b\U0001f3fc", "waving hand: Medium-Light Skin Tone", []string{"wave_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f44b\U0001f3fd", "waving hand: Medium Skin Tone", []string{"wave_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f44b\U0001f3fe", "waving hand: Medium-Dark Skin Tone", []string{"wave_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f44b\U0001f3ff", "waving hand: Dark Skin Tone", []string{"wave_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f44b\U0001f3fb", "waving hand: Light Skin Tone", []string{"wave_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fb\ufe0f", "person lifting weights: Light Skin Tone", []string{"weight_lifting_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fc\ufe0f", "person lifting weights: Medium-Light Skin Tone", []string{"weight_lifting_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fd\ufe0f", "person lifting weights: Medium Skin Tone", []string{"weight_lifting_Medium_Skin_Tone"}, "12.0", false}, @@ -2941,21 +2980,21 @@ var GemojiData = Gemoji{ {"\U0001f3cb\U0001f3fd\ufe0f\u200d\u2642\ufe0f", "man lifting weights: Medium Skin Tone", []string{"weight_lifting_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fe\ufe0f\u200d\u2642\ufe0f", "man lifting weights: Medium-Dark Skin Tone", []string{"weight_lifting_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3ff\ufe0f\u200d\u2642\ufe0f", "man lifting weights: Dark Skin Tone", []string{"weight_lifting_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f3cb\U0001f3ff\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Dark Skin Tone", []string{"weight_lifting_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fb\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Light Skin Tone", []string{"weight_lifting_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fc\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Medium-Light Skin Tone", []string{"weight_lifting_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fd\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Medium Skin Tone", []string{"weight_lifting_woman_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f3cb\U0001f3fe\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Medium-Dark Skin Tone", []string{"weight_lifting_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f468\U0001f3fb\u200d\U0001f9b3", "man: white hair: Light Skin Tone", []string{"white_haired_man_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f3cb\U0001f3ff\ufe0f\u200d\u2640\ufe0f", "woman lifting weights: Dark Skin Tone", []string{"weight_lifting_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fc\u200d\U0001f9b3", "man: white hair: Medium-Light Skin Tone", []string{"white_haired_man_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fd\u200d\U0001f9b3", "man: white hair: Medium Skin Tone", []string{"white_haired_man_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3fe\u200d\U0001f9b3", "man: white hair: Medium-Dark Skin Tone", []string{"white_haired_man_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f468\U0001f3ff\u200d\U0001f9b3", "man: white hair: Dark Skin Tone", []string{"white_haired_man_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\U0001f9b3", "woman: white hair: Medium-Dark Skin Tone", []string{"white_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f468\U0001f3fb\u200d\U0001f9b3", "man: white hair: Light Skin Tone", []string{"white_haired_man_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f9b3", "woman: white hair: Dark Skin Tone", []string{"white_haired_woman_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9b3", "woman: white hair: Light Skin Tone", []string{"white_haired_woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9b3", "woman: white hair: Medium-Light Skin Tone", []string{"white_haired_woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9b3", "woman: white hair: Medium Skin Tone", []string{"white_haired_woman_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\U0001f9b3", "woman: white hair: Medium-Dark Skin Tone", []string{"white_haired_woman_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb", "woman: Light Skin Tone", []string{"woman_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc", "woman: Medium-Light Skin Tone", []string{"woman_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd", "woman: Medium Skin Tone", []string{"woman_Medium_Skin_Tone"}, "12.0", false}, @@ -2966,26 +3005,26 @@ var GemojiData = Gemoji{ {"\U0001f469\U0001f3fd\u200d\U0001f3a8", "woman artist: Medium Skin Tone", []string{"woman_artist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f3a8", "woman artist: Medium-Dark Skin Tone", []string{"woman_artist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f3a8", "woman artist: Dark Skin Tone", []string{"woman_artist_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f680", "woman astronaut: Dark Skin Tone", []string{"woman_astronaut_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f680", "woman astronaut: Light Skin Tone", []string{"woman_astronaut_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f680", "woman astronaut: Medium-Light Skin Tone", []string{"woman_astronaut_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f680", "woman astronaut: Medium Skin Tone", []string{"woman_astronaut_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f680", "woman astronaut: Medium-Dark Skin Tone", []string{"woman_astronaut_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f680", "woman astronaut: Dark Skin Tone", []string{"woman_astronaut_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fb\u200d\u2640\ufe0f", "woman cartwheeling: Light Skin Tone", []string{"woman_cartwheeling_Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fc\u200d\u2640\ufe0f", "woman cartwheeling: Medium-Light Skin Tone", []string{"woman_cartwheeling_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fd\u200d\u2640\ufe0f", "woman cartwheeling: Medium Skin Tone", []string{"woman_cartwheeling_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3fe\u200d\u2640\ufe0f", "woman cartwheeling: Medium-Dark Skin Tone", []string{"woman_cartwheeling_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f938\U0001f3ff\u200d\u2640\ufe0f", "woman cartwheeling: Dark Skin Tone", []string{"woman_cartwheeling_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\U0001f373", "woman cook: Light Skin Tone", []string{"woman_cook_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f373", "woman cook: Medium-Light Skin Tone", []string{"woman_cook_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f373", "woman cook: Medium Skin Tone", []string{"woman_cook_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f373", "woman cook: Medium-Dark Skin Tone", []string{"woman_cook_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f373", "woman cook: Dark Skin Tone", []string{"woman_cook_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\U0001f373", "woman cook: Light Skin Tone", []string{"woman_cook_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f483\U0001f3fb", "woman dancing: Light Skin Tone", []string{"woman_dancing_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f483\U0001f3fc", "woman dancing: Medium-Light Skin Tone", []string{"woman_dancing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f483\U0001f3fd", "woman dancing: Medium Skin Tone", []string{"woman_dancing_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f483\U0001f3fe", "woman dancing: Medium-Dark Skin Tone", []string{"woman_dancing_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f483\U0001f3ff", "woman dancing: Dark Skin Tone", []string{"woman_dancing_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f483\U0001f3fb", "woman dancing: Light Skin Tone", []string{"woman_dancing_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f483\U0001f3fc", "woman dancing: Medium-Light Skin Tone", []string{"woman_dancing_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fb\u200d\u2640\ufe0f", "woman facepalming: Light Skin Tone", []string{"woman_facepalming_Light_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fc\u200d\u2640\ufe0f", "woman facepalming: Medium-Light Skin Tone", []string{"woman_facepalming_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f926\U0001f3fd\u200d\u2640\ufe0f", "woman facepalming: Medium Skin Tone", []string{"woman_facepalming_Medium_Skin_Tone"}, "12.0", false}, @@ -3011,21 +3050,21 @@ var GemojiData = Gemoji{ {"\U0001f469\U0001f3fd\u200d\u2695\ufe0f", "woman health worker: Medium Skin Tone", []string{"woman_health_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\u2695\ufe0f", "woman health worker: Medium-Dark Skin Tone", []string{"woman_health_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\u2695\ufe0f", "woman health worker: Dark Skin Tone", []string{"woman_health_worker_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\U0001f9bd", "woman in manual wheelchair: Medium-Dark Skin Tone", []string{"woman_in_manual_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f9bd", "woman in manual wheelchair: Dark Skin Tone", []string{"woman_in_manual_wheelchair_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9bd", "woman in manual wheelchair: Light Skin Tone", []string{"woman_in_manual_wheelchair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9bd", "woman in manual wheelchair: Medium-Light Skin Tone", []string{"woman_in_manual_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9bd", "woman in manual wheelchair: Medium Skin Tone", []string{"woman_in_manual_wheelchair_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\U0001f9bd", "woman in manual wheelchair: Medium-Dark Skin Tone", []string{"woman_in_manual_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f9bd", "woman in manual wheelchair: Dark Skin Tone", []string{"woman_in_manual_wheelchair_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\U0001f9bc", "woman in motorized wheelchair: Medium-Dark Skin Tone", []string{"woman_in_motorized_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f9bc", "woman in motorized wheelchair: Dark Skin Tone", []string{"woman_in_motorized_wheelchair_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9bc", "woman in motorized wheelchair: Light Skin Tone", []string{"woman_in_motorized_wheelchair_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f9bc", "woman in motorized wheelchair: Medium-Light Skin Tone", []string{"woman_in_motorized_wheelchair_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f9bc", "woman in motorized wheelchair: Medium Skin Tone", []string{"woman_in_motorized_wheelchair_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\u2696\ufe0f", "woman judge: Light Skin Tone", []string{"woman_judge_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\U0001f9bc", "woman in motorized wheelchair: Medium-Dark Skin Tone", []string{"woman_in_motorized_wheelchair_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f9bc", "woman in motorized wheelchair: Dark Skin Tone", []string{"woman_in_motorized_wheelchair_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\u2696\ufe0f", "woman judge: Medium-Light Skin Tone", []string{"woman_judge_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\u2696\ufe0f", "woman judge: Medium Skin Tone", []string{"woman_judge_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\u2696\ufe0f", "woman judge: Medium-Dark Skin Tone", []string{"woman_judge_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\u2696\ufe0f", "woman judge: Dark Skin Tone", []string{"woman_judge_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\u2696\ufe0f", "woman judge: Light Skin Tone", []string{"woman_judge_Light_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fb\u200d\u2640\ufe0f", "woman juggling: Light Skin Tone", []string{"woman_juggling_Light_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fc\u200d\u2640\ufe0f", "woman juggling: Medium-Light Skin Tone", []string{"woman_juggling_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f939\U0001f3fd\u200d\u2640\ufe0f", "woman juggling: Medium Skin Tone", []string{"woman_juggling_Medium_Skin_Tone"}, "12.0", false}, @@ -3041,66 +3080,66 @@ var GemojiData = Gemoji{ {"\U0001f469\U0001f3fd\u200d\U0001f4bc", "woman office worker: Medium Skin Tone", []string{"woman_office_worker_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f4bc", "woman office worker: Medium-Dark Skin Tone", []string{"woman_office_worker_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f4bc", "woman office worker: Dark Skin Tone", []string{"woman_office_worker_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\u2708\ufe0f", "woman pilot: Medium Skin Tone", []string{"woman_pilot_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\u2708\ufe0f", "woman pilot: Medium-Dark Skin Tone", []string{"woman_pilot_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\u2708\ufe0f", "woman pilot: Dark Skin Tone", []string{"woman_pilot_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\u2708\ufe0f", "woman pilot: Light Skin Tone", []string{"woman_pilot_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\u2708\ufe0f", "woman pilot: Medium-Light Skin Tone", []string{"woman_pilot_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fd\u200d\u2708\ufe0f", "woman pilot: Medium Skin Tone", []string{"woman_pilot_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\u2708\ufe0f", "woman pilot: Medium-Dark Skin Tone", []string{"woman_pilot_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fb\u200d\u2640\ufe0f", "woman playing handball: Light Skin Tone", []string{"woman_playing_handball_Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fc\u200d\u2640\ufe0f", "woman playing handball: Medium-Light Skin Tone", []string{"woman_playing_handball_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fd\u200d\u2640\ufe0f", "woman playing handball: Medium Skin Tone", []string{"woman_playing_handball_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3fe\u200d\u2640\ufe0f", "woman playing handball: Medium-Dark Skin Tone", []string{"woman_playing_handball_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93e\U0001f3ff\u200d\u2640\ufe0f", "woman playing handball: Dark Skin Tone", []string{"woman_playing_handball_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f93d\U0001f3fb\u200d\u2640\ufe0f", "woman playing water polo: Light Skin Tone", []string{"woman_playing_water_polo_Light_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3fc\u200d\u2640\ufe0f", "woman playing water polo: Medium-Light Skin Tone", []string{"woman_playing_water_polo_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3fd\u200d\u2640\ufe0f", "woman playing water polo: Medium Skin Tone", []string{"woman_playing_water_polo_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3fe\u200d\u2640\ufe0f", "woman playing water polo: Medium-Dark Skin Tone", []string{"woman_playing_water_polo_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f93d\U0001f3ff\u200d\u2640\ufe0f", "woman playing water polo: Dark Skin Tone", []string{"woman_playing_water_polo_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f93d\U0001f3fb\u200d\u2640\ufe0f", "woman playing water polo: Light Skin Tone", []string{"woman_playing_water_polo_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f52c", "woman scientist: Light Skin Tone", []string{"woman_scientist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f52c", "woman scientist: Medium-Light Skin Tone", []string{"woman_scientist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f52c", "woman scientist: Medium Skin Tone", []string{"woman_scientist_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f52c", "woman scientist: Medium-Dark Skin Tone", []string{"woman_scientist_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f52c", "woman scientist: Dark Skin Tone", []string{"woman_scientist_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f937\U0001f3ff\u200d\u2640\ufe0f", "woman shrugging: Dark Skin Tone", []string{"woman_shrugging_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fb\u200d\u2640\ufe0f", "woman shrugging: Light Skin Tone", []string{"woman_shrugging_Light_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fc\u200d\u2640\ufe0f", "woman shrugging: Medium-Light Skin Tone", []string{"woman_shrugging_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fd\u200d\u2640\ufe0f", "woman shrugging: Medium Skin Tone", []string{"woman_shrugging_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f937\U0001f3fe\u200d\u2640\ufe0f", "woman shrugging: Medium-Dark Skin Tone", []string{"woman_shrugging_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f937\U0001f3ff\u200d\u2640\ufe0f", "woman shrugging: Dark Skin Tone", []string{"woman_shrugging_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\U0001f3a4", "woman singer: Light Skin Tone", []string{"woman_singer_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f3a4", "woman singer: Medium-Light Skin Tone", []string{"woman_singer_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f3a4", "woman singer: Medium Skin Tone", []string{"woman_singer_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f3a4", "woman singer: Medium-Dark Skin Tone", []string{"woman_singer_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f3a4", "woman singer: Dark Skin Tone", []string{"woman_singer_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\U0001f3a4", "woman singer: Light Skin Tone", []string{"woman_singer_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\U0001f393", "woman student: Light Skin Tone", []string{"woman_student_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f393", "woman student: Medium-Light Skin Tone", []string{"woman_student_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f393", "woman student: Medium Skin Tone", []string{"woman_student_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f393", "woman student: Medium-Dark Skin Tone", []string{"woman_student_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f393", "woman student: Dark Skin Tone", []string{"woman_student_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\U0001f393", "woman student: Light Skin Tone", []string{"woman_student_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f3eb", "woman teacher: Dark Skin Tone", []string{"woman_teacher_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fb\u200d\U0001f3eb", "woman teacher: Light Skin Tone", []string{"woman_teacher_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f3eb", "woman teacher: Medium-Light Skin Tone", []string{"woman_teacher_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f3eb", "woman teacher: Medium Skin Tone", []string{"woman_teacher_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f3eb", "woman teacher: Medium-Dark Skin Tone", []string{"woman_teacher_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f3eb", "woman teacher: Dark Skin Tone", []string{"woman_teacher_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fb\u200d\U0001f3eb", "woman teacher: Light Skin Tone", []string{"woman_teacher_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fe\u200d\U0001f4bb", "woman technologist: Medium-Dark Skin Tone", []string{"woman_technologist_Medium-Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3ff\u200d\U0001f4bb", "woman technologist: Dark Skin Tone", []string{"woman_technologist_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f4bb", "woman technologist: Light Skin Tone", []string{"woman_technologist_Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fc\u200d\U0001f4bb", "woman technologist: Medium-Light Skin Tone", []string{"woman_technologist_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fd\u200d\U0001f4bb", "woman technologist: Medium Skin Tone", []string{"woman_technologist_Medium_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fe\u200d\U0001f4bb", "woman technologist: Medium-Dark Skin Tone", []string{"woman_technologist_Medium-Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3ff\u200d\U0001f4bb", "woman technologist: Dark Skin Tone", []string{"woman_technologist_Dark_Skin_Tone"}, "12.0", false}, - {"\U0001f9d5\U0001f3fc", "woman with headscarf: Medium-Light Skin Tone", []string{"woman_with_headscarf_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f9d5\U0001f3fd", "woman with headscarf: Medium Skin Tone", []string{"woman_with_headscarf_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f9d5\U0001f3fe", "woman with headscarf: Medium-Dark Skin Tone", []string{"woman_with_headscarf_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d5\U0001f3ff", "woman with headscarf: Dark Skin Tone", []string{"woman_with_headscarf_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f9d5\U0001f3fb", "woman with headscarf: Light Skin Tone", []string{"woman_with_headscarf_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fc\u200d\U0001f9af", "woman with white cane: Medium-Light Skin Tone", []string{"woman_with_probing_cane_Medium-Light_Skin_Tone"}, "12.0", false}, - {"\U0001f469\U0001f3fd\u200d\U0001f9af", "woman with white cane: Medium Skin Tone", []string{"woman_with_probing_cane_Medium_Skin_Tone"}, "12.0", false}, + {"\U0001f9d5\U0001f3fc", "woman with headscarf: Medium-Light Skin Tone", []string{"woman_with_headscarf_Medium-Light_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fe\u200d\U0001f9af", "woman with white cane: Medium-Dark Skin Tone", []string{"woman_with_probing_cane_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3ff\u200d\U0001f9af", "woman with white cane: Dark Skin Tone", []string{"woman_with_probing_cane_Dark_Skin_Tone"}, "12.0", false}, {"\U0001f469\U0001f3fb\u200d\U0001f9af", "woman with white cane: Light Skin Tone", []string{"woman_with_probing_cane_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3fb\u200d\u2640\ufe0f", "woman wearing turban: Light Skin Tone", []string{"woman_with_turban_Light_Skin_Tone"}, "12.0", false}, - {"\U0001f473\U0001f3fc\u200d\u2640\ufe0f", "woman wearing turban: Medium-Light Skin Tone", []string{"woman_with_turban_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fc\u200d\U0001f9af", "woman with white cane: Medium-Light Skin Tone", []string{"woman_with_probing_cane_Medium-Light_Skin_Tone"}, "12.0", false}, + {"\U0001f469\U0001f3fd\u200d\U0001f9af", "woman with white cane: Medium Skin Tone", []string{"woman_with_probing_cane_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fd\u200d\u2640\ufe0f", "woman wearing turban: Medium Skin Tone", []string{"woman_with_turban_Medium_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3fe\u200d\u2640\ufe0f", "woman wearing turban: Medium-Dark Skin Tone", []string{"woman_with_turban_Medium-Dark_Skin_Tone"}, "12.0", false}, {"\U0001f473\U0001f3ff\u200d\u2640\ufe0f", "woman wearing turban: Dark Skin Tone", []string{"woman_with_turban_Dark_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3fb\u200d\u2640\ufe0f", "woman wearing turban: Light Skin Tone", []string{"woman_with_turban_Light_Skin_Tone"}, "12.0", false}, + {"\U0001f473\U0001f3fc\u200d\u2640\ufe0f", "woman wearing turban: Medium-Light Skin Tone", []string{"woman_with_turban_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u270d\U0001f3fb\ufe0f", "writing hand: Light Skin Tone", []string{"writing_hand_Light_Skin_Tone"}, "12.0", false}, {"\u270d\U0001f3fc\ufe0f", "writing hand: Medium-Light Skin Tone", []string{"writing_hand_Medium-Light_Skin_Tone"}, "12.0", false}, {"\u270d\U0001f3fd\ufe0f", "writing hand: Medium Skin Tone", []string{"writing_hand_Medium_Skin_Tone"}, "12.0", false}, diff --git a/modules/eventsource/manager_run.go b/modules/eventsource/manager_run.go index 06d48454f..44e878fd4 100644 --- a/modules/eventsource/manager_run.go +++ b/modules/eventsource/manager_run.go @@ -8,7 +8,7 @@ import ( "context" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/graceful" @@ -72,7 +72,7 @@ loop: now := timeutil.TimeStampNow().Add(-2) - uidCounts, err := models.GetUIDsAndNotificationCounts(then, now) + uidCounts, err := activities_model.GetUIDsAndNotificationCounts(then, now) if err != nil { log.Error("Unable to get UIDcounts: %v", err) } diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go index a12452c40..4bc359689 100644 --- a/modules/git/commit_info_test.go +++ b/modules/git/commit_info_test.go @@ -6,13 +6,10 @@ package git import ( "context" - "os" "path/filepath" "testing" "time" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" ) @@ -20,18 +17,14 @@ const ( testReposDir = "tests/repos/" ) -func cloneRepo(url, name string) (string, error) { - repoDir, err := os.MkdirTemp("", name) - if err != nil { - return "", err - } +func cloneRepo(tb testing.TB, url string) (string, error) { + repoDir := tb.TempDir() if err := Clone(DefaultContext, url, repoDir, CloneRepoOptions{ Mirror: false, Bare: false, Quiet: true, Timeout: 5 * time.Minute, }); err != nil { - _ = util.RemoveAll(repoDir) return "", err } return repoDir, nil @@ -118,11 +111,10 @@ func TestEntries_GetCommitsInfo(t *testing.T) { testGetCommitsInfo(t, bareRepo1) - clonedPath, err := cloneRepo(bareRepo1Path, "repo1_TestEntries_GetCommitsInfo") + clonedPath, err := cloneRepo(t, bareRepo1Path) if err != nil { assert.NoError(t, err) } - defer util.RemoveAll(clonedPath) clonedRepo1, err := openRepositoryWithDefaultContext(clonedPath) if err != nil { assert.NoError(t, err) @@ -150,11 +142,10 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) { var commit *Commit var entries Entries var repo *Repository - repoPath, err := cloneRepo(benchmark.url, benchmark.name) + repoPath, err := cloneRepo(b, benchmark.url) if err != nil { b.Fatal(err) } - defer util.RemoveAll(repoPath) if repo, err = openRepositoryWithDefaultContext(repoPath); err != nil { b.Fatal(err) diff --git a/modules/git/foreachref/parser.go b/modules/git/foreachref/parser.go index eb8b77d90..bf83a10ed 100644 --- a/modules/git/foreachref/parser.go +++ b/modules/git/foreachref/parser.go @@ -68,8 +68,7 @@ func NewParser(r io.Reader, format Format) *Parser { // // It could, for example return something like: // -// { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" } -// +// { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" } func (p *Parser) Next() map[string]string { if !p.scanner.Scan() { return nil @@ -89,8 +88,7 @@ func (p *Parser) Err() error { // parseRef parses out all key-value pairs from a single reference block, such as // -// "objecttype tag\0refname:short v1.16.4\0object f460b7543ed500e49c133c2cd85c8c55ee9dbe27" -// +// "objecttype tag\0refname:short v1.16.4\0object f460b7543ed500e49c133c2cd85c8c55ee9dbe27" func (p *Parser) parseRef(refBlock string) (map[string]string, error) { if refBlock == "" { // must be at EOF diff --git a/modules/git/git.go b/modules/git/git.go index 99849f1f0..28899222e 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -185,11 +185,6 @@ func InitFull(ctx context.Context) (err error) { globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2") } - // By default partial clones are disabled, enable them from git v2.22 - if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil { - globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true") - } - // Explicitly disable credential helper, otherwise Git credentials might leak if CheckGitVersionAtLeast("2.9") == nil { globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=") @@ -286,7 +281,20 @@ func syncGitConfig() (err error) { } } - return nil + // By default partial clones are disabled, enable them from git v2.22 + if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil { + if err = configSet("uploadpack.allowfilter", "true"); err != nil { + return err + } + err = configSet("uploadpack.allowAnySHA1InWant", "true") + } else { + if err = configUnsetAll("uploadpack.allowfilter", "true"); err != nil { + return err + } + err = configUnsetAll("uploadpack.allowAnySHA1InWant", "true") + } + + return err } // CheckGitVersionAtLeast check git version is at least the constraint version diff --git a/modules/git/ref.go b/modules/git/ref.go index 9fd071ce5..2f459148a 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -4,7 +4,10 @@ package git -import "strings" +import ( + "regexp" + "strings" +) const ( // RemotePrefix is the base directory of the remotes information of git. @@ -15,6 +18,29 @@ const ( pullLen = len(PullPrefix) ) +// refNamePatternInvalid is regular expression with unallowed characters in git reference name +// They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere. +// They cannot have question-mark ?, asterisk *, or open bracket [ anywhere +var refNamePatternInvalid = regexp.MustCompile( + `[\000-\037\177 \\~^:?*[]|` + // No absolutely invalid characters + `(?:^[/.])|` + // Not HasPrefix("/") or "." + `(?:/\.)|` + // no "/." + `(?:\.lock$)|(?:\.lock/)|` + // No ".lock/"" or ".lock" at the end + `(?:\.\.)|` + // no ".." anywhere + `(?://)|` + // no "//" anywhere + `(?:@{)|` + // no "@{" + `(?:[/.]$)|` + // no terminal '/' or '.' + `(?:^@$)`) // Not "@" + +// IsValidRefPattern ensures that the provided string could be a valid reference +func IsValidRefPattern(name string) bool { + return !refNamePatternInvalid.MatchString(name) +} + +func SanitizeRefPattern(name string) string { + return refNamePatternInvalid.ReplaceAllString(name, "_") +} + // Reference represents a Git ref. type Reference struct { Name string diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index e528af0ff..efea307b3 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -138,7 +138,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co // ConvertToSHA1 returns a Hash object from a potential ID string func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == 40 && SHAPattern.MatchString(commitID) { + if len(commitID) == 40 && IsValidSHAPattern(commitID) { sha1, err := NewIDFromString(commitID) if err == nil { return sha1, nil diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 577c9f475..589a7eae0 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -40,7 +40,7 @@ func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, stri if tmpRemote != "origin" { tmpBaseName := RemotePrefix + tmpRemote + "/tmp_" + base // Fetch commit into a temporary branch in order to be able to handle commits and tags - _, _, err := NewCommand(repo.Ctx, "fetch", tmpRemote, base+":"+tmpBaseName).RunStdString(&RunOpts{Dir: repo.Path}) + _, _, err := NewCommand(repo.Ctx, "fetch", "--no-tags", tmpRemote, "--", base+":"+tmpBaseName).RunStdString(&RunOpts{Dir: repo.Path}) if err == nil { base = tmpBaseName } diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 245920c2b..63f7254de 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -10,19 +10,16 @@ import ( "path/filepath" "testing" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" ) func TestGetFormatPatch(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - clonedPath, err := cloneRepo(bareRepo1Path, "repo1_TestGetFormatPatch") + clonedPath, err := cloneRepo(t, bareRepo1Path) if err != nil { assert.NoError(t, err) return } - defer util.RemoveAll(clonedPath) repo, err := openRepositoryWithDefaultContext(clonedPath) if err != nil { @@ -84,12 +81,11 @@ func TestReadWritePullHead(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") // As we are writing we should clone the repository first - clonedPath, err := cloneRepo(bareRepo1Path, "TestReadWritePullHead") + clonedPath, err := cloneRepo(t, bareRepo1Path) if err != nil { assert.NoError(t, err) return } - defer util.RemoveAll(clonedPath) repo, err := openRepositoryWithDefaultContext(clonedPath) if err != nil { diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index 9d8467286..6a00473bb 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -8,8 +8,6 @@ import ( "path/filepath" "testing" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -38,12 +36,11 @@ func TestRepository_GetTags(t *testing.T) { func TestRepository_GetTag(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetTag") + clonedPath, err := cloneRepo(t, bareRepo1Path) if err != nil { assert.NoError(t, err) return } - defer util.RemoveAll(clonedPath) bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) if err != nil { @@ -143,12 +140,11 @@ func TestRepository_GetTag(t *testing.T) { func TestRepository_GetAnnotatedTag(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetAnnotatedTag") + clonedPath, err := cloneRepo(t, bareRepo1Path) if err != nil { assert.NoError(t, err) return } - defer util.RemoveAll(clonedPath) bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) if err != nil { diff --git a/modules/git/sha1.go b/modules/git/sha1.go index 2da74733d..15f282c6e 100644 --- a/modules/git/sha1.go +++ b/modules/git/sha1.go @@ -19,7 +19,12 @@ const EmptySHA = "0000000000000000000000000000000000000000" const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" // SHAPattern can be used to determine if a string is an valid sha -var SHAPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) +var shaPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) + +// IsValidSHAPattern will check if the provided string matches the SHA Pattern +func IsValidSHAPattern(sha string) bool { + return shaPattern.MatchString(sha) +} // MustID always creates a new SHA1 from a [20]byte array with no validation of input. func MustID(b []byte) SHA1 { diff --git a/modules/git/signature_gogit.go b/modules/git/signature_gogit.go index fe81cd97d..6f1c98420 100644 --- a/modules/git/signature_gogit.go +++ b/modules/git/signature_gogit.go @@ -19,8 +19,10 @@ import ( type Signature = object.Signature // Helper to get a signature from the commit line, which looks like these: -// author Patrick Gundlach 1378823654 +0200 -// author Patrick Gundlach Thu, 07 Apr 2005 22:13:13 +0200 +// +// author Patrick Gundlach 1378823654 +0200 +// author Patrick Gundlach Thu, 07 Apr 2005 22:13:13 +0200 +// // but without the "author " at the beginning (this method should) // be used for author and committer. // diff --git a/modules/git/signature_nogogit.go b/modules/git/signature_nogogit.go index 2fc8dde04..07a3b79f1 100644 --- a/modules/git/signature_nogogit.go +++ b/modules/git/signature_nogogit.go @@ -37,8 +37,10 @@ func (s *Signature) Decode(b []byte) { } // Helper to get a signature from the commit line, which looks like these: -// author Patrick Gundlach 1378823654 +0200 -// author Patrick Gundlach Thu, 07 Apr 2005 22:13:13 +0200 +// +// author Patrick Gundlach 1378823654 +0200 +// author Patrick Gundlach Thu, 07 Apr 2005 22:13:13 +0200 +// // but without the "author " at the beginning (this method should) // be used for author and committer. func newSignatureFromCommitline(line []byte) (sig *Signature, err error) { diff --git a/modules/graceful/manager.go b/modules/graceful/manager.go index 8766cfca0..21f019fb5 100644 --- a/modules/graceful/manager.go +++ b/modules/graceful/manager.go @@ -24,11 +24,12 @@ const ( stateTerminate ) -// There are three places that could inherit sockets: +// There are some places that could inherit sockets: // // * HTTP or HTTPS main listener +// * HTTP or HTTPS install listener // * HTTP redirection fallback -// * SSH +// * Builtin SSH listener // // If you add an additional place you must increment this number // and add a function to call manager.InformCleanup if it's not going to be used @@ -305,8 +306,9 @@ func (g *Manager) setState(st state) { g.state = st } -// InformCleanup tells the cleanup wait group that we have either taken a listener -// or will not be taking a listener +// InformCleanup tells the cleanup wait group that we have either taken a listener or will not be taking a listener. +// At the moment the total number of servers (numberOfServersToCreate) are pre-defined as a const before global init, +// so this function MUST be called if a server is not used. func (g *Manager) InformCleanup() { g.createServerWaitGroup.Done() } diff --git a/modules/graceful/manager_windows.go b/modules/graceful/manager_windows.go index e7e619f53..10c1d67b9 100644 --- a/modules/graceful/manager_windows.go +++ b/modules/graceful/manager_windows.go @@ -114,9 +114,9 @@ func (g *Manager) start() { // Execute makes Manager implement svc.Handler func (g *Manager) Execute(args []string, changes <-chan svc.ChangeRequest, status chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) { if setting.StartupTimeout > 0 { - status <- svc.Status{State: svc.StartPending} - } else { status <- svc.Status{State: svc.StartPending, WaitHint: uint32(setting.StartupTimeout / time.Millisecond)} + } else { + status <- svc.Status{State: svc.StartPending} } log.Trace("Awaiting server start-up") diff --git a/modules/graceful/server.go b/modules/graceful/server.go index 159a9879d..30a460a94 100644 --- a/modules/graceful/server.go +++ b/modules/graceful/server.go @@ -16,6 +16,7 @@ import ( "time" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/proxyprotocol" "code.gitea.io/gitea/modules/setting" ) @@ -79,16 +80,27 @@ func NewServer(network, address, name string) *Server { // ListenAndServe listens on the provided network address and then calls Serve // to handle requests on incoming connections. -func (srv *Server) ListenAndServe(serve ServeFunction) error { +func (srv *Server) ListenAndServe(serve ServeFunction, useProxyProtocol bool) error { go srv.awaitShutdown() - l, err := GetListener(srv.network, srv.address) + listener, err := GetListener(srv.network, srv.address) if err != nil { log.Error("Unable to GetListener: %v", err) return err } - srv.listener = newWrappedListener(l, srv) + // we need to wrap the listener to take account of our lifecycle + listener = newWrappedListener(listener, srv) + + // Now we need to take account of ProxyProtocol settings... + if useProxyProtocol { + listener = &proxyprotocol.Listener{ + Listener: listener, + ProxyHeaderTimeout: setting.ProxyProtocolHeaderTimeout, + AcceptUnknown: setting.ProxyProtocolAcceptUnknown, + } + } + srv.listener = listener srv.BeforeBegin(srv.network, srv.address) @@ -97,22 +109,44 @@ func (srv *Server) ListenAndServe(serve ServeFunction) error { // ListenAndServeTLSConfig listens on the provided network address and then calls // Serve to handle requests on incoming TLS connections. -func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFunction) error { +func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFunction, useProxyProtocol, proxyProtocolTLSBridging bool) error { go srv.awaitShutdown() if tlsConfig.MinVersion == 0 { tlsConfig.MinVersion = tls.VersionTLS12 } - l, err := GetListener(srv.network, srv.address) + listener, err := GetListener(srv.network, srv.address) if err != nil { log.Error("Unable to get Listener: %v", err) return err } - wl := newWrappedListener(l, srv) - srv.listener = tls.NewListener(wl, tlsConfig) + // we need to wrap the listener to take account of our lifecycle + listener = newWrappedListener(listener, srv) + // Now we need to take account of ProxyProtocol settings... If we're not bridging then we expect that the proxy will forward the connection to us + if useProxyProtocol && !proxyProtocolTLSBridging { + listener = &proxyprotocol.Listener{ + Listener: listener, + ProxyHeaderTimeout: setting.ProxyProtocolHeaderTimeout, + AcceptUnknown: setting.ProxyProtocolAcceptUnknown, + } + } + + // Now handle the tls protocol + listener = tls.NewListener(listener, tlsConfig) + + // Now if we're bridging then we need the proxy to tell us who we're bridging for... + if useProxyProtocol && proxyProtocolTLSBridging { + listener = &proxyprotocol.Listener{ + Listener: listener, + ProxyHeaderTimeout: setting.ProxyProtocolHeaderTimeout, + AcceptUnknown: setting.ProxyProtocolAcceptUnknown, + } + } + + srv.listener = listener srv.BeforeBegin(srv.network, srv.address) return srv.Serve(serve) diff --git a/modules/graceful/server_http.go b/modules/graceful/server_http.go index f7b22ceb5..8ab2bdf41 100644 --- a/modules/graceful/server_http.go +++ b/modules/graceful/server_http.go @@ -28,14 +28,14 @@ func newHTTPServer(network, address, name string, handler http.Handler) (*Server // HTTPListenAndServe listens on the provided network address and then calls Serve // to handle requests on incoming connections. -func HTTPListenAndServe(network, address, name string, handler http.Handler) error { +func HTTPListenAndServe(network, address, name string, handler http.Handler, useProxyProtocol bool) error { server, lHandler := newHTTPServer(network, address, name, handler) - return server.ListenAndServe(lHandler) + return server.ListenAndServe(lHandler, useProxyProtocol) } // HTTPListenAndServeTLSConfig listens on the provided network address and then calls Serve // to handle requests on incoming connections. -func HTTPListenAndServeTLSConfig(network, address, name string, tlsConfig *tls.Config, handler http.Handler) error { +func HTTPListenAndServeTLSConfig(network, address, name string, tlsConfig *tls.Config, handler http.Handler, useProxyProtocol, proxyProtocolTLSBridging bool) error { server, lHandler := newHTTPServer(network, address, name, handler) - return server.ListenAndServeTLSConfig(tlsConfig, lHandler) + return server.ListenAndServeTLSConfig(tlsConfig, lHandler, useProxyProtocol, proxyProtocolTLSBridging) } diff --git a/modules/indexer/code/bleve_test.go b/modules/indexer/code/bleve_test.go index 37ed2eb9f..a34d54bc0 100644 --- a/modules/indexer/code/bleve_test.go +++ b/modules/indexer/code/bleve_test.go @@ -5,11 +5,9 @@ package code import ( - "os" "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) @@ -17,13 +15,7 @@ import ( func TestBleveIndexAndSearch(t *testing.T) { unittest.PrepareTestEnv(t) - dir, err := os.MkdirTemp("", "bleve.index") - assert.NoError(t, err) - if err != nil { - assert.Fail(t, "Unable to create temporary directory") - return - } - defer util.RemoveAll(dir) + dir := t.TempDir() idx, _, err := NewBleveIndexer(dir) if err != nil { diff --git a/modules/indexer/issues/bleve_test.go b/modules/indexer/issues/bleve_test.go index 68a7831a3..42d22f06a 100644 --- a/modules/indexer/issues/bleve_test.go +++ b/modules/indexer/issues/bleve_test.go @@ -6,22 +6,13 @@ package issues import ( "context" - "os" "testing" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" ) func TestBleveIndexAndSearch(t *testing.T) { - dir, err := os.MkdirTemp("", "bleve.index") - assert.NoError(t, err) - if err != nil { - assert.Fail(t, "Unable to create temporary directory") - return - } - defer util.RemoveAll(dir) + dir := t.TempDir() indexer := NewBleveIndexer(dir) defer indexer.Close() @@ -30,7 +21,7 @@ func TestBleveIndexAndSearch(t *testing.T) { return } - err = indexer.Index([]*IndexerData{ + err := indexer.Index([]*IndexerData{ { ID: 1, RepoID: 2, diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 6bafcbdf2..e8b9ff837 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -6,7 +6,6 @@ package issues import ( "context" - "os" "path" "path/filepath" "testing" @@ -14,7 +13,6 @@ import ( "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" _ "code.gitea.io/gitea/models" @@ -32,11 +30,7 @@ func TestBleveSearchIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) setting.Cfg = ini.Empty() - tmpIndexerDir, err := os.MkdirTemp("", "issues-indexer") - if err != nil { - assert.Fail(t, "Unable to create temporary directory: %v", err) - return - } + tmpIndexerDir := t.TempDir() setting.Cfg.Section("queue.issue_indexer").Key("DATADIR").MustString(path.Join(tmpIndexerDir, "issues.queue")) @@ -44,7 +38,6 @@ func TestBleveSearchIssues(t *testing.T) { setting.Indexer.IssuePath = path.Join(tmpIndexerDir, "issues.queue") defer func() { setting.Indexer.IssuePath = oldIssuePath - util.RemoveAll(tmpIndexerDir) }() setting.Indexer.IssueType = "bleve" diff --git a/modules/issue/template/template.go b/modules/issue/template/template.go new file mode 100644 index 000000000..a4c0fb5aa --- /dev/null +++ b/modules/issue/template/template.go @@ -0,0 +1,392 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package template + +import ( + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + + api "code.gitea.io/gitea/modules/structs" + + "gitea.com/go-chi/binding" +) + +// Validate checks whether an IssueTemplate is considered valid, and returns the first error +func Validate(template *api.IssueTemplate) error { + if err := validateMetadata(template); err != nil { + return err + } + if template.Type() == api.IssueTemplateTypeYaml { + if err := validateYaml(template); err != nil { + return err + } + } + return nil +} + +func validateMetadata(template *api.IssueTemplate) error { + if strings.TrimSpace(template.Name) == "" { + return fmt.Errorf("'name' is required") + } + if strings.TrimSpace(template.About) == "" { + return fmt.Errorf("'about' is required") + } + return nil +} + +func validateYaml(template *api.IssueTemplate) error { + if len(template.Fields) == 0 { + return fmt.Errorf("'body' is required") + } + ids := map[string]struct{}{} + for idx, field := range template.Fields { + if err := validateID(field, idx, ids); err != nil { + return err + } + if err := validateLabel(field, idx); err != nil { + return err + } + + position := newErrorPosition(idx, field.Type) + switch field.Type { + case api.IssueFormFieldTypeMarkdown: + if err := validateStringItem(position, field.Attributes, true, "value"); err != nil { + return err + } + case api.IssueFormFieldTypeTextarea: + if err := validateStringItem(position, field.Attributes, false, + "description", + "placeholder", + "value", + "render", + ); err != nil { + return err + } + case api.IssueFormFieldTypeInput: + if err := validateStringItem(position, field.Attributes, false, + "description", + "placeholder", + "value", + ); err != nil { + return err + } + if err := validateBoolItem(position, field.Validations, "is_number"); err != nil { + return err + } + if err := validateStringItem(position, field.Validations, false, "regex"); err != nil { + return err + } + case api.IssueFormFieldTypeDropdown: + if err := validateStringItem(position, field.Attributes, false, "description"); err != nil { + return err + } + if err := validateBoolItem(position, field.Attributes, "multiple"); err != nil { + return err + } + if err := validateOptions(field, idx); err != nil { + return err + } + case api.IssueFormFieldTypeCheckboxes: + if err := validateStringItem(position, field.Attributes, false, "description"); err != nil { + return err + } + if err := validateOptions(field, idx); err != nil { + return err + } + default: + return position.Errorf("unknown type") + } + + if err := validateRequired(field, idx); err != nil { + return err + } + } + return nil +} + +func validateLabel(field *api.IssueFormField, idx int) error { + if field.Type == api.IssueFormFieldTypeMarkdown { + // The label is not required for a markdown field + return nil + } + return validateStringItem(newErrorPosition(idx, field.Type), field.Attributes, true, "label") +} + +func validateRequired(field *api.IssueFormField, idx int) error { + if field.Type == api.IssueFormFieldTypeMarkdown || field.Type == api.IssueFormFieldTypeCheckboxes { + // The label is not required for a markdown or checkboxes field + return nil + } + return validateBoolItem(newErrorPosition(idx, field.Type), field.Validations, "required") +} + +func validateID(field *api.IssueFormField, idx int, ids map[string]struct{}) error { + if field.Type == api.IssueFormFieldTypeMarkdown { + // The ID is not required for a markdown field + return nil + } + + position := newErrorPosition(idx, field.Type) + if field.ID == "" { + // If the ID is empty in yaml, template.Unmarshal will auto autofill it, so it cannot be empty + return position.Errorf("'id' is required") + } + if binding.AlphaDashPattern.MatchString(field.ID) { + return position.Errorf("'id' should contain only alphanumeric, '-' and '_'") + } + if _, ok := ids[field.ID]; ok { + return position.Errorf("'id' should be unique") + } + ids[field.ID] = struct{}{} + return nil +} + +func validateOptions(field *api.IssueFormField, idx int) error { + if field.Type != api.IssueFormFieldTypeDropdown && field.Type != api.IssueFormFieldTypeCheckboxes { + return nil + } + position := newErrorPosition(idx, field.Type) + + options, ok := field.Attributes["options"].([]interface{}) + if !ok || len(options) == 0 { + return position.Errorf("'options' is required and should be a array") + } + + for optIdx, option := range options { + position := newErrorPosition(idx, field.Type, optIdx) + switch field.Type { + case api.IssueFormFieldTypeDropdown: + if _, ok := option.(string); !ok { + return position.Errorf("should be a string") + } + case api.IssueFormFieldTypeCheckboxes: + opt, ok := option.(map[interface{}]interface{}) + if !ok { + return position.Errorf("should be a dictionary") + } + if label, ok := opt["label"].(string); !ok || label == "" { + return position.Errorf("'label' is required and should be a string") + } + + if required, ok := opt["required"]; ok { + if _, ok := required.(bool); !ok { + return position.Errorf("'required' should be a bool") + } + } + } + } + return nil +} + +func validateStringItem(position errorPosition, m map[string]interface{}, required bool, names ...string) error { + for _, name := range names { + v, ok := m[name] + if !ok { + if required { + return position.Errorf("'%s' is required", name) + } + return nil + } + attr, ok := v.(string) + if !ok { + return position.Errorf("'%s' should be a string", name) + } + if strings.TrimSpace(attr) == "" && required { + return position.Errorf("'%s' is required", name) + } + } + return nil +} + +func validateBoolItem(position errorPosition, m map[string]interface{}, names ...string) error { + for _, name := range names { + v, ok := m[name] + if !ok { + return nil + } + if _, ok := v.(bool); !ok { + return position.Errorf("'%s' should be a bool", name) + } + } + return nil +} + +type errorPosition string + +func (p errorPosition) Errorf(format string, a ...interface{}) error { + return fmt.Errorf(string(p)+": "+format, a...) +} + +func newErrorPosition(fieldIdx int, fieldType api.IssueFormFieldType, optionIndex ...int) errorPosition { + ret := fmt.Sprintf("body[%d](%s)", fieldIdx, fieldType) + if len(optionIndex) > 0 { + ret += fmt.Sprintf(", option[%d]", optionIndex[0]) + } + return errorPosition(ret) +} + +// RenderToMarkdown renders template to markdown with specified values +func RenderToMarkdown(template *api.IssueTemplate, values url.Values) string { + builder := &strings.Builder{} + + for _, field := range template.Fields { + f := &valuedField{ + IssueFormField: field, + Values: values, + } + if f.ID == "" { + continue + } + f.WriteTo(builder) + } + + return builder.String() +} + +type valuedField struct { + *api.IssueFormField + url.Values +} + +func (f *valuedField) WriteTo(builder *strings.Builder) { + if f.Type == api.IssueFormFieldTypeMarkdown { + // markdown blocks do not appear in output + return + } + + // write label + _, _ = fmt.Fprintf(builder, "### %s\n\n", f.Label()) + + blankPlaceholder := "_No response_\n" + + // write body + switch f.Type { + case api.IssueFormFieldTypeCheckboxes: + for _, option := range f.Options() { + checked := " " + if option.IsChecked() { + checked = "x" + } + _, _ = fmt.Fprintf(builder, "- [%s] %s\n", checked, option.Label()) + } + case api.IssueFormFieldTypeDropdown: + var checkeds []string + for _, option := range f.Options() { + if option.IsChecked() { + checkeds = append(checkeds, option.Label()) + } + } + if len(checkeds) > 0 { + _, _ = fmt.Fprintf(builder, "%s\n", strings.Join(checkeds, ", ")) + } else { + _, _ = fmt.Fprint(builder, blankPlaceholder) + } + case api.IssueFormFieldTypeInput: + if value := f.Value(); value == "" { + _, _ = fmt.Fprint(builder, blankPlaceholder) + } else { + _, _ = fmt.Fprintf(builder, "%s\n", value) + } + case api.IssueFormFieldTypeTextarea: + if value := f.Value(); value == "" { + _, _ = fmt.Fprint(builder, blankPlaceholder) + } else if render := f.Render(); render != "" { + quotes := minQuotes(value) + _, _ = fmt.Fprintf(builder, "%s%s\n%s\n%s\n", quotes, f.Render(), value, quotes) + } else { + _, _ = fmt.Fprintf(builder, "%s\n", value) + } + } + _, _ = fmt.Fprintln(builder) +} + +func (f *valuedField) Label() string { + if label, ok := f.Attributes["label"].(string); ok { + return label + } + return "" +} + +func (f *valuedField) Render() string { + if render, ok := f.Attributes["render"].(string); ok { + return render + } + return "" +} + +func (f *valuedField) Value() string { + return strings.TrimSpace(f.Get(fmt.Sprintf("form-field-" + f.ID))) +} + +func (f *valuedField) Options() []*valuedOption { + if options, ok := f.Attributes["options"].([]interface{}); ok { + ret := make([]*valuedOption, 0, len(options)) + for i, option := range options { + ret = append(ret, &valuedOption{ + index: i, + data: option, + field: f, + }) + } + return ret + } + return nil +} + +type valuedOption struct { + index int + data interface{} + field *valuedField +} + +func (o *valuedOption) Label() string { + switch o.field.Type { + case api.IssueFormFieldTypeDropdown: + if label, ok := o.data.(string); ok { + return label + } + case api.IssueFormFieldTypeCheckboxes: + if vs, ok := o.data.(map[interface{}]interface{}); ok { + if v, ok := vs["label"].(string); ok { + return v + } + } + } + return "" +} + +func (o *valuedOption) IsChecked() bool { + switch o.field.Type { + case api.IssueFormFieldTypeDropdown: + checks := strings.Split(o.field.Get(fmt.Sprintf("form-field-%s", o.field.ID)), ",") + idx := strconv.Itoa(o.index) + for _, v := range checks { + if v == idx { + return true + } + } + return false + case api.IssueFormFieldTypeCheckboxes: + return o.field.Get(fmt.Sprintf("form-field-%s-%d", o.field.ID, o.index)) == "on" + } + return false +} + +var minQuotesRegex = regexp.MustCompilePOSIX("^`{3,}") + +// minQuotes return 3 or more back-quotes. +// If n back-quotes exists, use n+1 back-quotes to quote. +func minQuotes(value string) string { + ret := "```" + for _, v := range minQuotesRegex.FindAllString(value, -1) { + if len(v) >= len(ret) { + ret = v + "`" + } + } + return ret +} diff --git a/modules/issue/template/template_test.go b/modules/issue/template/template_test.go new file mode 100644 index 000000000..883e1e078 --- /dev/null +++ b/modules/issue/template/template_test.go @@ -0,0 +1,645 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package template + +import ( + "net/url" + "reflect" + "testing" + + "code.gitea.io/gitea/modules/json" + api "code.gitea.io/gitea/modules/structs" +) + +func TestValidate(t *testing.T) { + tests := []struct { + name string + content string + wantErr string + }{ + { + name: "miss name", + content: ``, + wantErr: "'name' is required", + }, + { + name: "miss about", + content: ` +name: "test" +`, + wantErr: "'about' is required", + }, + { + name: "miss body", + content: ` +name: "test" +about: "this is about" +`, + wantErr: "'body' is required", + }, + { + name: "markdown miss value", + content: ` +name: "test" +about: "this is about" +body: + - type: "markdown" +`, + wantErr: "body[0](markdown): 'value' is required", + }, + { + name: "markdown invalid value", + content: ` +name: "test" +about: "this is about" +body: + - type: "markdown" + attributes: + value: true +`, + wantErr: "body[0](markdown): 'value' should be a string", + }, + { + name: "markdown empty value", + content: ` +name: "test" +about: "this is about" +body: + - type: "markdown" + attributes: + value: "" +`, + wantErr: "body[0](markdown): 'value' is required", + }, + { + name: "textarea invalid id", + content: ` +name: "test" +about: "this is about" +body: + - type: "textarea" + id: "?" +`, + wantErr: "body[0](textarea): 'id' should contain only alphanumeric, '-' and '_'", + }, + { + name: "textarea miss label", + content: ` +name: "test" +about: "this is about" +body: + - type: "textarea" + id: "1" +`, + wantErr: "body[0](textarea): 'label' is required", + }, + { + name: "textarea conflict id", + content: ` +name: "test" +about: "this is about" +body: + - type: "textarea" + id: "1" + attributes: + label: "a" + - type: "textarea" + id: "1" + attributes: + label: "b" +`, + wantErr: "body[1](textarea): 'id' should be unique", + }, + { + name: "textarea invalid description", + content: ` +name: "test" +about: "this is about" +body: + - type: "textarea" + id: "1" + attributes: + label: "a" + description: true +`, + wantErr: "body[0](textarea): 'description' should be a string", + }, + { + name: "textarea invalid required", + content: ` +name: "test" +about: "this is about" +body: + - type: "textarea" + id: "1" + attributes: + label: "a" + validations: + required: "on" +`, + wantErr: "body[0](textarea): 'required' should be a bool", + }, + { + name: "input invalid description", + content: ` +name: "test" +about: "this is about" +body: + - type: "input" + id: "1" + attributes: + label: "a" + description: true +`, + wantErr: "body[0](input): 'description' should be a string", + }, + { + name: "input invalid is_number", + content: ` +name: "test" +about: "this is about" +body: + - type: "input" + id: "1" + attributes: + label: "a" + validations: + is_number: "yes" +`, + wantErr: "body[0](input): 'is_number' should be a bool", + }, + { + name: "input invalid regex", + content: ` +name: "test" +about: "this is about" +body: + - type: "input" + id: "1" + attributes: + label: "a" + validations: + regex: true +`, + wantErr: "body[0](input): 'regex' should be a string", + }, + { + name: "dropdown invalid description", + content: ` +name: "test" +about: "this is about" +body: + - type: "dropdown" + id: "1" + attributes: + label: "a" + description: true +`, + wantErr: "body[0](dropdown): 'description' should be a string", + }, + { + name: "dropdown invalid multiple", + content: ` +name: "test" +about: "this is about" +body: + - type: "dropdown" + id: "1" + attributes: + label: "a" + multiple: "on" +`, + wantErr: "body[0](dropdown): 'multiple' should be a bool", + }, + { + name: "checkboxes invalid description", + content: ` +name: "test" +about: "this is about" +body: + - type: "checkboxes" + id: "1" + attributes: + label: "a" + description: true +`, + wantErr: "body[0](checkboxes): 'description' should be a string", + }, + { + name: "invalid type", + content: ` +name: "test" +about: "this is about" +body: + - type: "video" + id: "1" + attributes: + label: "a" +`, + wantErr: "body[0](video): unknown type", + }, + { + name: "dropdown miss options", + content: ` +name: "test" +about: "this is about" +body: + - type: "dropdown" + id: "1" + attributes: + label: "a" +`, + wantErr: "body[0](dropdown): 'options' is required and should be a array", + }, + { + name: "dropdown invalid options", + content: ` +name: "test" +about: "this is about" +body: + - type: "dropdown" + id: "1" + attributes: + label: "a" + options: + - "a" + - true +`, + wantErr: "body[0](dropdown), option[1]: should be a string", + }, + { + name: "checkboxes invalid options", + content: ` +name: "test" +about: "this is about" +body: + - type: "checkboxes" + id: "1" + attributes: + label: "a" + options: + - "a" + - true +`, + wantErr: "body[0](checkboxes), option[0]: should be a dictionary", + }, + { + name: "checkboxes option miss label", + content: ` +name: "test" +about: "this is about" +body: + - type: "checkboxes" + id: "1" + attributes: + label: "a" + options: + - required: true +`, + wantErr: "body[0](checkboxes), option[0]: 'label' is required and should be a string", + }, + { + name: "checkboxes option invalid required", + content: ` +name: "test" +about: "this is about" +body: + - type: "checkboxes" + id: "1" + attributes: + label: "a" + options: + - label: "a" + required: "on" +`, + wantErr: "body[0](checkboxes), option[0]: 'required' should be a bool", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tmpl, err := unmarshal("test.yaml", []byte(tt.content)) + if err != nil { + t.Fatal(err) + } + if err := Validate(tmpl); (err == nil) != (tt.wantErr == "") || err != nil && err.Error() != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %q", err, tt.wantErr) + } + }) + } + + t.Run("valid", func(t *testing.T) { + content := ` +name: Name +title: Title +about: About +labels: ["label1", "label2"] +ref: Ref +body: + - type: markdown + id: id1 + attributes: + value: Value of the markdown + - type: textarea + id: id2 + attributes: + label: Label of textarea + description: Description of textarea + placeholder: Placeholder of textarea + value: Value of textarea + render: bash + validations: + required: true + - type: input + id: id3 + attributes: + label: Label of input + description: Description of input + placeholder: Placeholder of input + value: Value of input + validations: + required: true + is_number: true + regex: "[a-zA-Z0-9]+" + - type: dropdown + id: id4 + attributes: + label: Label of dropdown + description: Description of dropdown + multiple: true + options: + - Option 1 of dropdown + - Option 2 of dropdown + - Option 3 of dropdown + validations: + required: true + - type: checkboxes + id: id5 + attributes: + label: Label of checkboxes + description: Description of checkboxes + options: + - label: Option 1 of checkboxes + required: true + - label: Option 2 of checkboxes + required: false + - label: Option 3 of checkboxes + required: true +` + want := &api.IssueTemplate{ + Name: "Name", + Title: "Title", + About: "About", + Labels: []string{"label1", "label2"}, + Ref: "Ref", + Fields: []*api.IssueFormField{ + { + Type: "markdown", + ID: "id1", + Attributes: map[string]interface{}{ + "value": "Value of the markdown", + }, + }, + { + Type: "textarea", + ID: "id2", + Attributes: map[string]interface{}{ + "label": "Label of textarea", + "description": "Description of textarea", + "placeholder": "Placeholder of textarea", + "value": "Value of textarea", + "render": "bash", + }, + Validations: map[string]interface{}{ + "required": true, + }, + }, + { + Type: "input", + ID: "id3", + Attributes: map[string]interface{}{ + "label": "Label of input", + "description": "Description of input", + "placeholder": "Placeholder of input", + "value": "Value of input", + }, + Validations: map[string]interface{}{ + "required": true, + "is_number": true, + "regex": "[a-zA-Z0-9]+", + }, + }, + { + Type: "dropdown", + ID: "id4", + Attributes: map[string]interface{}{ + "label": "Label of dropdown", + "description": "Description of dropdown", + "multiple": true, + "options": []interface{}{ + "Option 1 of dropdown", + "Option 2 of dropdown", + "Option 3 of dropdown", + }, + }, + Validations: map[string]interface{}{ + "required": true, + }, + }, + { + Type: "checkboxes", + ID: "id5", + Attributes: map[string]interface{}{ + "label": "Label of checkboxes", + "description": "Description of checkboxes", + "options": []interface{}{ + map[interface{}]interface{}{"label": "Option 1 of checkboxes", "required": true}, + map[interface{}]interface{}{"label": "Option 2 of checkboxes", "required": false}, + map[interface{}]interface{}{"label": "Option 3 of checkboxes", "required": true}, + }, + }, + }, + }, + FileName: "test.yaml", + } + got, err := unmarshal("test.yaml", []byte(content)) + if err != nil { + t.Fatal(err) + } + if err := Validate(got); err != nil { + t.Errorf("Validate() error = %v", err) + } + if !reflect.DeepEqual(want, got) { + jsonWant, _ := json.Marshal(want) + jsonGot, _ := json.Marshal(got) + t.Errorf("want:\n%s\ngot:\n%s", jsonWant, jsonGot) + } + }) +} + +func TestRenderToMarkdown(t *testing.T) { + type args struct { + template string + values url.Values + } + tests := []struct { + name string + args args + want string + }{ + { + name: "normal", + args: args{ + template: ` +name: Name +title: Title +about: About +labels: ["label1", "label2"] +ref: Ref +body: + - type: markdown + id: id1 + attributes: + value: Value of the markdown + - type: textarea + id: id2 + attributes: + label: Label of textarea + description: Description of textarea + placeholder: Placeholder of textarea + value: Value of textarea + render: bash + validations: + required: true + - type: input + id: id3 + attributes: + label: Label of input + description: Description of input + placeholder: Placeholder of input + value: Value of input + validations: + required: true + is_number: true + regex: "[a-zA-Z0-9]+" + - type: dropdown + id: id4 + attributes: + label: Label of dropdown + description: Description of dropdown + multiple: true + options: + - Option 1 of dropdown + - Option 2 of dropdown + - Option 3 of dropdown + validations: + required: true + - type: checkboxes + id: id5 + attributes: + label: Label of checkboxes + description: Description of checkboxes + options: + - label: Option 1 of checkboxes + required: true + - label: Option 2 of checkboxes + required: false + - label: Option 3 of checkboxes + required: true +`, + values: map[string][]string{ + "form-field-id2": {"Value of id2"}, + "form-field-id3": {"Value of id3"}, + "form-field-id4": {"0,1"}, + "form-field-id5-0": {"on"}, + "form-field-id5-2": {"on"}, + }, + }, + want: `### Label of textarea + +` + "```bash\nValue of id2\n```" + ` + +### Label of input + +Value of id3 + +### Label of dropdown + +Option 1 of dropdown, Option 2 of dropdown + +### Label of checkboxes + +- [x] Option 1 of checkboxes +- [ ] Option 2 of checkboxes +- [x] Option 3 of checkboxes + +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + template, err := Unmarshal("test.yaml", []byte(tt.args.template)) + if err != nil { + t.Fatal(err) + } + if got := RenderToMarkdown(template, tt.args.values); got != tt.want { + t.Errorf("RenderToMarkdown() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_minQuotes(t *testing.T) { + type args struct { + value string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "without quote", + args: args{ + value: "Hello\nWorld", + }, + want: "```", + }, + { + name: "with 1 quote", + args: args{ + value: "Hello\nWorld\n`text`\n", + }, + want: "```", + }, + { + name: "with 3 quotes", + args: args{ + value: "Hello\nWorld\n`text`\n```go\ntext\n```\n", + }, + want: "````", + }, + { + name: "with more quotes", + args: args{ + value: "Hello\nWorld\n`text`\n```go\ntext\n```\n``````````bash\ntext\n``````````\n", + }, + want: "```````````", + }, + { + name: "not leading quotes", + args: args{ + value: "Hello\nWorld`text````go\ntext`````````````bash\ntext``````````\n", + }, + want: "```", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := minQuotes(tt.args.value); got != tt.want { + t.Errorf("minQuotes() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/modules/issue/template/unmarshal.go b/modules/issue/template/unmarshal.go new file mode 100644 index 000000000..e695d1e1c --- /dev/null +++ b/modules/issue/template/unmarshal.go @@ -0,0 +1,125 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package template + +import ( + "fmt" + "io" + "path/filepath" + "strconv" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" + + "gopkg.in/yaml.v2" +) + +// CouldBe indicates a file with the filename could be a template, +// it is a low cost check before further processing. +func CouldBe(filename string) bool { + it := &api.IssueTemplate{ + FileName: filename, + } + return it.Type() != "" +} + +// Unmarshal parses out a valid template from the content +func Unmarshal(filename string, content []byte) (*api.IssueTemplate, error) { + it, err := unmarshal(filename, content) + if err != nil { + return nil, err + } + + if err := Validate(it); err != nil { + return nil, err + } + + return it, nil +} + +// UnmarshalFromEntry parses out a valid template from the blob in entry +func UnmarshalFromEntry(entry *git.TreeEntry, dir string) (*api.IssueTemplate, error) { + return unmarshalFromEntry(entry, filepath.Join(dir, entry.Name())) +} + +// UnmarshalFromCommit parses out a valid template from the commit +func UnmarshalFromCommit(commit *git.Commit, filename string) (*api.IssueTemplate, error) { + entry, err := commit.GetTreeEntryByPath(filename) + if err != nil { + return nil, fmt.Errorf("get entry for %q: %w", filename, err) + } + return unmarshalFromEntry(entry, filename) +} + +// UnmarshalFromRepo parses out a valid template from the head commit of the branch +func UnmarshalFromRepo(repo *git.Repository, branch, filename string) (*api.IssueTemplate, error) { + commit, err := repo.GetBranchCommit(branch) + if err != nil { + return nil, fmt.Errorf("get commit on branch %q: %w", branch, err) + } + + return UnmarshalFromCommit(commit, filename) +} + +func unmarshalFromEntry(entry *git.TreeEntry, filename string) (*api.IssueTemplate, error) { + if size := entry.Blob().Size(); size > setting.UI.MaxDisplayFileSize { + return nil, fmt.Errorf("too large: %v > MaxDisplayFileSize", size) + } + + r, err := entry.Blob().DataAsync() + if err != nil { + return nil, fmt.Errorf("data async: %w", err) + } + defer r.Close() + + content, err := io.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("read all: %w", err) + } + + return Unmarshal(filename, content) +} + +func unmarshal(filename string, content []byte) (*api.IssueTemplate, error) { + it := &api.IssueTemplate{ + FileName: filename, + } + + // Compatible with treating description as about + compatibleTemplate := &struct { + About string `yaml:"description"` + }{} + + if typ := it.Type(); typ == api.IssueTemplateTypeMarkdown { + templateBody, err := markdown.ExtractMetadata(string(content), it) + if err != nil { + return nil, err + } + it.Content = templateBody + if it.About == "" { + if _, err := markdown.ExtractMetadata(string(content), compatibleTemplate); err == nil && compatibleTemplate.About != "" { + it.About = compatibleTemplate.About + } + } + } else if typ == api.IssueTemplateTypeYaml { + if err := yaml.Unmarshal(content, it); err != nil { + return nil, fmt.Errorf("yaml unmarshal: %w", err) + } + if it.About == "" { + if err := yaml.Unmarshal(content, compatibleTemplate); err == nil && compatibleTemplate.About != "" { + it.About = compatibleTemplate.About + } + } + for i, v := range it.Fields { + if v.ID == "" { + v.ID = strconv.Itoa(i) + } + } + } + + return it, nil +} diff --git a/modules/log/file.go b/modules/log/file.go index d9a529e67..8110a9587 100644 --- a/modules/log/file.go +++ b/modules/log/file.go @@ -93,6 +93,7 @@ func NewFileLogger() LoggerProvider { // Init file logger with json config. // config like: +// // { // "filename":"log/gogs.log", // "maxsize":1<<30, diff --git a/modules/log/file_test.go b/modules/log/file_test.go index c3074b69d..cc2b9fe07 100644 --- a/modules/log/file_test.go +++ b/modules/log/file_test.go @@ -14,15 +14,11 @@ import ( "testing" "time" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" ) func TestFileLoggerFails(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "TestFileLogger") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() prefix := "TestPrefix " level := INFO @@ -34,7 +30,7 @@ func TestFileLoggerFails(t *testing.T) { // assert.True(t, ok) // Fail if there is bad json - err = fileLogger.Init("{") + err := fileLogger.Init("{") assert.Error(t, err) // Fail if there is no filename @@ -47,9 +43,7 @@ func TestFileLoggerFails(t *testing.T) { } func TestFileLogger(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "TestFileLogger") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() prefix := "TestPrefix " level := INFO @@ -150,9 +144,7 @@ func TestFileLogger(t *testing.T) { } func TestCompressFileLogger(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "TestFileLogger") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() prefix := "TestPrefix " level := INFO @@ -210,9 +202,7 @@ func TestCompressFileLogger(t *testing.T) { } func TestCompressOldFile(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "TestFileLogger") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() fname := filepath.Join(tmpDir, "test") nonGzip := filepath.Join(tmpDir, "test-nonGzip") diff --git a/modules/log/smtp.go b/modules/log/smtp.go index c5163292e..1706517d6 100644 --- a/modules/log/smtp.go +++ b/modules/log/smtp.go @@ -48,6 +48,7 @@ func NewSMTPLogger() LoggerProvider { // Init smtp writer with json config. // config like: +// // { // "Username":"example@gmail.com", // "password:"password", diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index a7cf81250..370bc2182 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -24,7 +24,7 @@ import ( var localMetas = map[string]string{ "user": "gogits", "repo": "gogs", - "repoPath": "../../integrations/gitea-repositories-meta/user13/repo11.git/", + "repoPath": "../../tests/gitea-repositories-meta/user13/repo11.git/", } func TestMain(m *testing.M) { diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 732fe1a6b..fdbc291c9 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -29,7 +29,7 @@ const ( var localMetas = map[string]string{ "user": "gogits", "repo": "gogs", - "repoPath": "../../../integrations/gitea-repositories-meta/user13/repo11.git/", + "repoPath": "../../../tests/gitea-repositories-meta/user13/repo11.git/", } func TestMain(m *testing.M) { diff --git a/modules/markup/markdown/meta_test.go b/modules/markup/markdown/meta_test.go index f525777a5..939646f8f 100644 --- a/modules/markup/markdown/meta_test.go +++ b/modules/markup/markdown/meta_test.go @@ -6,6 +6,7 @@ package markdown import ( "fmt" + "strings" "testing" "code.gitea.io/gitea/modules/structs" @@ -13,6 +14,16 @@ import ( "github.com/stretchr/testify/assert" ) +func validateMetadata(it structs.IssueTemplate) bool { + /* + A legacy to keep the unit tests working. + Copied from the method "func (it IssueTemplate) Valid() bool", the original method has been removed. + Because it becomes quite complicated to validate an issue template which is support yaml form now. + The new way to validate an issue template is to call the Validate in modules/issue/template, + */ + return strings.TrimSpace(it.Name) != "" && strings.TrimSpace(it.About) != "" +} + func TestExtractMetadata(t *testing.T) { t.Run("ValidFrontAndBody", func(t *testing.T) { var meta structs.IssueTemplate @@ -20,7 +31,7 @@ func TestExtractMetadata(t *testing.T) { assert.NoError(t, err) assert.Equal(t, bodyTest, body) assert.Equal(t, metaTest, meta) - assert.True(t, meta.Valid()) + assert.True(t, validateMetadata(meta)) }) t.Run("NoFirstSeparator", func(t *testing.T) { @@ -41,7 +52,7 @@ func TestExtractMetadata(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "", body) assert.Equal(t, metaTest, meta) - assert.True(t, meta.Valid()) + assert.True(t, validateMetadata(meta)) }) } diff --git a/modules/markup/mdstripper/mdstripper.go b/modules/markup/mdstripper/mdstripper.go index 64079194f..c7f8ee69f 100644 --- a/modules/markup/mdstripper/mdstripper.go +++ b/modules/markup/mdstripper/mdstripper.go @@ -141,7 +141,7 @@ func (r *stripRenderer) AddOptions(...renderer.Option) { } // StripMarkdown parses markdown content by removing all markup and code blocks -// in order to extract links and other references +// in order to extract links and other references func StripMarkdown(rawBytes []byte) (string, []string) { buf, links := StripMarkdownBytes(rawBytes) return string(buf), links @@ -153,7 +153,7 @@ var ( ) // StripMarkdownBytes parses markdown content by removing all markup and code blocks -// in order to extract links and other references +// in order to extract links and other references func StripMarkdownBytes(rawBytes []byte) ([]byte, []string) { once.Do(func() { gdMarkdown := goldmark.New( diff --git a/modules/metrics/collector.go b/modules/metrics/collector.go index 069633a56..dcd80b05a 100755 --- a/modules/metrics/collector.go +++ b/modules/metrics/collector.go @@ -5,7 +5,7 @@ package metrics import ( - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "github.com/prometheus/client_golang/prometheus" ) @@ -225,7 +225,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) { // Collect returns the metrics with values func (c Collector) Collect(ch chan<- prometheus.Metric) { - stats := models.GetStatistic() + stats := activities_model.GetStatistic() ch <- prometheus.MustNewConstMetric( c.Accesses, diff --git a/modules/migration/pullrequest.go b/modules/migration/pullrequest.go index eaa0dd45e..dd520cd63 100644 --- a/modules/migration/pullrequest.go +++ b/modules/migration/pullrequest.go @@ -26,7 +26,7 @@ type PullRequest struct { Updated time.Time Closed *time.Time Labels []*Label - PatchURL string `yaml:"patch_url"` + PatchURL string `yaml:"patch_url"` // SECURITY: This must be safe to download directly from Merged bool MergedTime *time.Time `yaml:"merged_time"` MergeCommitSHA string `yaml:"merge_commit_sha"` @@ -37,6 +37,7 @@ type PullRequest struct { Reactions []*Reaction ForeignIndex int64 Context DownloaderContext `yaml:"-"` + EnsuredSafe bool `yaml:"ensured_safe"` } func (p *PullRequest) GetLocalIndex() int64 { return p.Number } @@ -55,9 +56,9 @@ func (p PullRequest) GetGitRefName() string { // PullRequestBranch represents a pull request branch type PullRequestBranch struct { - CloneURL string `yaml:"clone_url"` - Ref string - SHA string + CloneURL string `yaml:"clone_url"` // SECURITY: This must be safe to download from + Ref string // SECURITY: this must be a git.IsValidRefPattern + SHA string // SECURITY: this must be a git.IsValidSHAPattern RepoName string `yaml:"repo_name"` OwnerName string `yaml:"owner_name"` } diff --git a/modules/migration/release.go b/modules/migration/release.go index cbdf01a3e..923b3817b 100644 --- a/modules/migration/release.go +++ b/modules/migration/release.go @@ -18,15 +18,16 @@ type ReleaseAsset struct { DownloadCount *int `yaml:"download_count"` Created time.Time Updated time.Time - DownloadURL *string `yaml:"download_url"` + + DownloadURL *string `yaml:"download_url"` // SECURITY: It is the responsibility of downloader to make sure this is safe // if DownloadURL is nil, the function should be invoked - DownloadFunc func() (io.ReadCloser, error) `yaml:"-"` + DownloadFunc func() (io.ReadCloser, error) `yaml:"-"` // SECURITY: It is the responsibility of downloader to make sure this is safe } // Release represents a release type Release struct { - TagName string `yaml:"tag_name"` - TargetCommitish string `yaml:"target_commitish"` + TagName string `yaml:"tag_name"` // SECURITY: This must pass git.IsValidRefPattern + TargetCommitish string `yaml:"target_commitish"` // SECURITY: This must pass git.IsValidRefPattern Name string Body string Draft bool diff --git a/modules/migration/repo.go b/modules/migration/repo.go index d0d62de8d..75622595d 100644 --- a/modules/migration/repo.go +++ b/modules/migration/repo.go @@ -12,7 +12,7 @@ type Repository struct { IsPrivate bool `yaml:"is_private"` IsMirror bool `yaml:"is_mirror"` Description string - CloneURL string `yaml:"clone_url"` + CloneURL string `yaml:"clone_url"` // SECURITY: This must be checked to ensure that is safe to be used OriginalURL string `yaml:"original_url"` DefaultBranch string } diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index 3b2ad75b4..f7d5a72ed 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -245,7 +245,7 @@ func getRedisTLSOptions(uri *url.URL) *tls.Config { if len(skipverify) > 0 { skipverify, err := strconv.ParseBool(skipverify) - if err != nil { + if err == nil { tlsConfig.InsecureSkipVerify = skipverify } } @@ -254,7 +254,7 @@ func getRedisTLSOptions(uri *url.URL) *tls.Config { if len(insecureskipverify) > 0 { insecureskipverify, err := strconv.ParseBool(insecureskipverify) - if err != nil { + if err == nil { tlsConfig.InsecureSkipVerify = insecureskipverify } } diff --git a/modules/nosql/manager_redis_test.go b/modules/nosql/manager_redis_test.go index 3d9453213..99a8856f1 100644 --- a/modules/nosql/manager_redis_test.go +++ b/modules/nosql/manager_redis_test.go @@ -27,6 +27,24 @@ func TestRedisPasswordOpt(t *testing.T) { } } +func TestSkipVerifyOpt(t *testing.T) { + uri, _ := url.Parse("rediss://myredis/0?skipverify=true") + tlsConfig := getRedisTLSOptions(uri) + + if !tlsConfig.InsecureSkipVerify { + t.Fail() + } +} + +func TestInsecureSkipVerifyOpt(t *testing.T) { + uri, _ := url.Parse("rediss://myredis/0?insecureskipverify=true") + tlsConfig := getRedisTLSOptions(uri) + + if !tlsConfig.InsecureSkipVerify { + t.Fail() + } +} + func TestRedisSentinelUsernameOpt(t *testing.T) { uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass") opts := getRedisOptions(uri).Failover() diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index e438f4148..d3ff8b156 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -9,7 +9,7 @@ import ( "path" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -45,10 +45,10 @@ func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*u } repo := issue.Repo - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: issue.Poster.ID, ActUser: issue.Poster, - OpType: models.ActionCreateIssue, + OpType: activities_model.ActionCreateIssue, Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title), RepoID: repo.ID, Repo: repo, @@ -62,7 +62,7 @@ func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*u func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { // Compose comment action, could be plain comment, close or reopen issue/pull request. // This object will be used to notify watchers in the end of function. - act := &models.Action{ + act := &activities_model.Action{ ActUserID: doer.ID, ActUser: doer, Content: fmt.Sprintf("%d|%s", issue.Index, ""), @@ -74,19 +74,19 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *i } // Check comment type. if closeOrReopen { - act.OpType = models.ActionCloseIssue + act.OpType = activities_model.ActionCloseIssue if issue.IsPull { - act.OpType = models.ActionClosePullRequest + act.OpType = activities_model.ActionClosePullRequest } } else { - act.OpType = models.ActionReopenIssue + act.OpType = activities_model.ActionReopenIssue if issue.IsPull { - act.OpType = models.ActionReopenPullRequest + act.OpType = activities_model.ActionReopenPullRequest } } // Notify watchers for whatever action comes in, ignore if no action type. - if err := models.NotifyWatchers(act); err != nil { + if err := activities_model.NotifyWatchers(act); err != nil { log.Error("NotifyWatchers: %v", err) } } @@ -95,7 +95,7 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *i func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { - act := &models.Action{ + act := &activities_model.Action{ ActUserID: doer.ID, ActUser: doer, RepoID: issue.Repo.ID, @@ -116,13 +116,13 @@ func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *r act.Content = fmt.Sprintf("%d|%s", issue.Index, truncatedContent) if issue.IsPull { - act.OpType = models.ActionCommentPull + act.OpType = activities_model.ActionCommentPull } else { - act.OpType = models.ActionCommentIssue + act.OpType = activities_model.ActionCommentIssue } // Notify watchers for whatever action comes in, ignore if no action type. - if err := models.NotifyWatchers(act); err != nil { + if err := activities_model.NotifyWatchers(act); err != nil { log.Error("NotifyWatchers: %v", err) } } @@ -141,10 +141,10 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, me return } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: pull.Issue.Poster.ID, ActUser: pull.Issue.Poster, - OpType: models.ActionCreatePullRequest, + OpType: activities_model.ActionCreatePullRequest, Content: fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title), RepoID: pull.Issue.Repo.ID, Repo: pull.Issue.Repo, @@ -155,10 +155,10 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, me } func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionRenameRepo, + OpType: activities_model.ActionRenameRepo, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -169,10 +169,10 @@ func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *rep } func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionTransferRepo, + OpType: activities_model.ActionTransferRepo, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -183,10 +183,10 @@ func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *r } func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionCreateRepo, + OpType: activities_model.ActionCreateRepo, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -196,10 +196,10 @@ func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo * } func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionCreateRepo, + OpType: activities_model.ActionCreateRepo, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -221,15 +221,15 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r return } - actions := make([]*models.Action, 0, 10) + actions := make([]*activities_model.Action, 0, 10) for _, lines := range review.CodeComments { for _, comments := range lines { for _, comm := range comments { - actions = append(actions, &models.Action{ + actions = append(actions, &activities_model.Action{ ActUserID: review.Reviewer.ID, ActUser: review.Reviewer, Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]), - OpType: models.ActionCommentPull, + OpType: activities_model.ActionCommentPull, RepoID: review.Issue.RepoID, Repo: review.Issue.Repo, IsPrivate: review.Issue.Repo.IsPrivate, @@ -241,7 +241,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r } if review.Type != issues_model.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { - action := &models.Action{ + action := &activities_model.Action{ ActUserID: review.Reviewer.ID, ActUser: review.Reviewer, Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]), @@ -254,26 +254,26 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r switch review.Type { case issues_model.ReviewTypeApprove: - action.OpType = models.ActionApprovePullRequest + action.OpType = activities_model.ActionApprovePullRequest case issues_model.ReviewTypeReject: - action.OpType = models.ActionRejectPullRequest + action.OpType = activities_model.ActionRejectPullRequest default: - action.OpType = models.ActionCommentPull + action.OpType = activities_model.ActionCommentPull } actions = append(actions, action) } - if err := models.NotifyWatchersActions(actions); err != nil { + if err := activities_model.NotifyWatchersActions(actions); err != nil { log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err) } } func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionMergePullRequest, + OpType: activities_model.ActionMergePullRequest, Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title), RepoID: pr.Issue.Repo.ID, Repo: pr.Issue.Repo, @@ -288,10 +288,10 @@ func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *i if len(review.OriginalAuthor) > 0 { reviewerName = review.OriginalAuthor } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, - OpType: models.ActionPullReviewDismissed, + OpType: activities_model.ActionPullReviewDismissed, Content: fmt.Sprintf("%d|%s|%s", review.Issue.Index, reviewerName, comment.Content), RepoID: review.Issue.Repo.ID, Repo: review.Issue.Repo, @@ -310,19 +310,19 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m return } - opType := models.ActionCommitRepo + opType := activities_model.ActionCommitRepo // Check it's tag push or branch. if opts.IsTag() { - opType = models.ActionPushTag + opType = activities_model.ActionPushTag if opts.IsDelRef() { - opType = models.ActionDeleteTag + opType = activities_model.ActionDeleteTag } } else if opts.IsDelRef() { - opType = models.ActionDeleteBranch + opType = activities_model.ActionDeleteBranch } - if err = models.NotifyWatchers(&models.Action{ + if err = activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: pusher.ID, ActUser: pusher, OpType: opType, @@ -337,12 +337,12 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m } func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { - opType := models.ActionCommitRepo + opType := activities_model.ActionCommitRepo if refType == "tag" { // has sent same action in `NotifyPushCommits`, so skip it. return } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, OpType: opType, @@ -356,12 +356,12 @@ func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model } func (a *actionNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { - opType := models.ActionDeleteBranch + opType := activities_model.ActionDeleteBranch if refType == "tag" { // has sent same action in `NotifyPushCommits`, so skip it. return } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: doer.ID, ActUser: doer, OpType: opType, @@ -381,10 +381,10 @@ func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *re return } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: repo.OwnerID, ActUser: repo.MustOwner(), - OpType: models.ActionMirrorSyncPush, + OpType: activities_model.ActionMirrorSyncPush, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -396,10 +396,10 @@ func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *re } func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: repo.OwnerID, ActUser: repo.MustOwner(), - OpType: models.ActionMirrorSyncCreate, + OpType: activities_model.ActionMirrorSyncCreate, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -410,10 +410,10 @@ func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_m } func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: repo.OwnerID, ActUser: repo.MustOwner(), - OpType: models.ActionMirrorSyncDelete, + OpType: activities_model.ActionMirrorSyncDelete, RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, @@ -423,15 +423,15 @@ func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_m } } -func (a *actionNotifier) NotifyNewRelease(rel *models.Release) { +func (a *actionNotifier) NotifyNewRelease(rel *repo_model.Release) { if err := rel.LoadAttributes(); err != nil { log.Error("NotifyNewRelease: %v", err) return } - if err := models.NotifyWatchers(&models.Action{ + if err := activities_model.NotifyWatchers(&activities_model.Action{ ActUserID: rel.PublisherID, ActUser: rel.Publisher, - OpType: models.ActionPublishRelease, + OpType: activities_model.ActionPublishRelease, RepoID: rel.RepoID, Repo: rel.Repo, IsPrivate: rel.Repo.IsPrivate, diff --git a/modules/notification/action/action_test.go b/modules/notification/action/action_test.go index f6de0d675..79a938d6c 100644 --- a/modules/notification/action/action_test.go +++ b/modules/notification/action/action_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -35,8 +35,8 @@ func TestRenameRepoAction(t *testing.T) { repo.Name = newRepoName repo.LowerName = strings.ToLower(newRepoName) - actionBean := &models.Action{ - OpType: models.ActionRenameRepo, + actionBean := &activities_model.Action{ + OpType: activities_model.ActionRenameRepo, ActUserID: user.ID, ActUser: user, RepoID: repo.ID, @@ -49,5 +49,5 @@ func TestRenameRepoAction(t *testing.T) { NewNotifier().NotifyRenameRepository(user, repo, oldRepoName) unittest.AssertExistsAndLoadBean(t, actionBean) - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 31fa8f5f1..d6cec92e1 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -5,7 +5,6 @@ package base import ( - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -46,9 +45,12 @@ type Notifier interface { issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) NotifyUpdateComment(*user_model.User, *issues_model.Comment, string) NotifyDeleteComment(*user_model.User, *issues_model.Comment) - NotifyNewRelease(rel *models.Release) - NotifyUpdateRelease(doer *user_model.User, rel *models.Release) - NotifyDeleteRelease(doer *user_model.User, rel *models.Release) + NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) + NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) + NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) + NotifyNewRelease(rel *repo_model.Release) + NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) + NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index d336f0930..b113ae79e 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -5,7 +5,6 @@ package base import ( - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -79,16 +78,28 @@ func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model. func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { } +// NotifyNewWikiPage places a place holder function +func (*NullNotifier) NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { +} + +// NotifyEditWikiPage places a place holder function +func (*NullNotifier) NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { +} + +// NotifyDeleteWikiPage places a place holder function +func (*NullNotifier) NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) { +} + // NotifyNewRelease places a place holder function -func (*NullNotifier) NotifyNewRelease(rel *models.Release) { +func (*NullNotifier) NotifyNewRelease(rel *repo_model.Release) { } // NotifyUpdateRelease places a place holder function -func (*NullNotifier) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { +func (*NullNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { } // NotifyDeleteRelease places a place holder function -func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { +func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { } // NotifyIssueChangeMilestone places a place holder function diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go index 5085656c1..100b4eb36 100644 --- a/modules/notification/mail/mail.go +++ b/modules/notification/mail/mail.go @@ -7,7 +7,7 @@ package mail import ( "fmt" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -35,15 +35,15 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) defer finished() - var act models.ActionType + var act activities_model.ActionType if comment.Type == issues_model.CommentTypeClose { - act = models.ActionCloseIssue + act = activities_model.ActionCloseIssue } else if comment.Type == issues_model.CommentTypeReopen { - act = models.ActionReopenIssue + act = activities_model.ActionReopenIssue } else if comment.Type == issues_model.CommentTypeComment { - act = models.ActionCommentIssue + act = activities_model.ActionCommentIssue } else if comment.Type == issues_model.CommentTypeCode { - act = models.ActionCommentIssue + act = activities_model.ActionCommentIssue } else if comment.Type == issues_model.CommentTypePullRequestPush { act = 0 } @@ -54,24 +54,24 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep } func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { - if err := mailer.MailParticipants(issue, issue.Poster, models.ActionCreateIssue, mentions); err != nil { + if err := mailer.MailParticipants(issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil { log.Error("MailParticipants: %v", err) } } func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { - var actionType models.ActionType + var actionType activities_model.ActionType if issue.IsPull { if isClosed { - actionType = models.ActionClosePullRequest + actionType = activities_model.ActionClosePullRequest } else { - actionType = models.ActionReopenPullRequest + actionType = activities_model.ActionReopenPullRequest } } else { if isClosed { - actionType = models.ActionCloseIssue + actionType = activities_model.ActionCloseIssue } else { - actionType = models.ActionReopenIssue + actionType = activities_model.ActionReopenIssue } } @@ -86,14 +86,14 @@ func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issu return } if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { - if err := mailer.MailParticipants(issue, doer, models.ActionPullRequestReadyForReview, nil); err != nil { + if err := mailer.MailParticipants(issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil { log.Error("MailParticipants: %v", err) } } } func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { - if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, models.ActionCreatePullRequest, mentions); err != nil { + if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil { log.Error("MailParticipants: %v", err) } } @@ -102,13 +102,13 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r * ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() - var act models.ActionType + var act activities_model.ActionType if comment.Type == issues_model.CommentTypeClose { - act = models.ActionCloseIssue + act = activities_model.ActionCloseIssue } else if comment.Type == issues_model.CommentTypeReopen { - act = models.ActionReopenIssue + act = activities_model.ActionReopenIssue } else if comment.Type == issues_model.CommentTypeComment { - act = models.ActionCommentPull + act = activities_model.ActionCommentPull } if err := mailer.MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { log.Error("MailParticipantsComment: %v", err) @@ -148,7 +148,7 @@ func (m *mailNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer log.Error("pr.LoadIssue: %v", err) return } - if err := mailer.MailParticipants(pr.Issue, doer, models.ActionMergePullRequest, nil); err != nil { + if err := mailer.MailParticipants(pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil { log.Error("MailParticipants: %v", err) } } @@ -184,12 +184,12 @@ func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *i ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID)) defer finished() - if err := mailer.MailParticipantsComment(ctx, comment, models.ActionPullReviewDismissed, review.Issue, nil); err != nil { + if err := mailer.MailParticipantsComment(ctx, comment, activities_model.ActionPullReviewDismissed, review.Issue, nil); err != nil { log.Error("MailParticipantsComment: %v", err) } } -func (m *mailNotifier) NotifyNewRelease(rel *models.Release) { +func (m *mailNotifier) NotifyNewRelease(rel *repo_model.Release) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyNewRelease rel[%d]%s in [%d]", rel.ID, rel.Title, rel.RepoID)) defer finished() diff --git a/modules/notification/notification.go b/modules/notification/notification.go index bdfed90b7..693c7f5c2 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -5,7 +5,6 @@ package notification import ( - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -41,6 +40,27 @@ func NewContext() { RegisterNotifier(mirror.NewNotifier()) } +// NotifyNewWikiPage notifies creating new wiki pages to notifiers +func NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { + for _, notifier := range notifiers { + notifier.NotifyNewWikiPage(doer, repo, page, comment) + } +} + +// NotifyEditWikiPage notifies editing or renaming wiki pages to notifiers +func NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { + for _, notifier := range notifiers { + notifier.NotifyEditWikiPage(doer, repo, page, comment) + } +} + +// NotifyDeleteWikiPage notifies deleting wiki pages to notifiers +func NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) { + for _, notifier := range notifiers { + notifier.NotifyDeleteWikiPage(doer, repo, page) + } +} + // NotifyCreateIssueComment notifies issue comment related message to notifiers func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, @@ -142,21 +162,21 @@ func NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { } // NotifyNewRelease notifies new release to notifiers -func NotifyNewRelease(rel *models.Release) { +func NotifyNewRelease(rel *repo_model.Release) { for _, notifier := range notifiers { notifier.NotifyNewRelease(rel) } } // NotifyUpdateRelease notifies update release to notifiers -func NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { +func NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { for _, notifier := range notifiers { notifier.NotifyUpdateRelease(doer, rel) } } // NotifyDeleteRelease notifies delete release to notifiers -func NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { +func NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { for _, notifier := range notifiers { notifier.NotifyDeleteRelease(doer, rel) } diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 74866a336..5e5196a70 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -5,7 +5,7 @@ package ui import ( - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -42,7 +42,7 @@ func NewNotifier() base.Notifier { func (ns *notificationService) handle(data ...queue.Data) []queue.Data { for _, datum := range data { opts := datum.(issueNotificationOpts) - if err := models.CreateOrUpdateIssueNotifications(opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { + if err := activities_model.CreateOrUpdateIssueNotifications(opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { log.Error("Was unable to create issue notification: %v", err) } } @@ -237,7 +237,7 @@ func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, is } func (ns *notificationService) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) { - if err := models.CreateRepoTransferNotification(doer, newOwner, repo); err != nil { + if err := activities_model.CreateRepoTransferNotification(doer, newOwner, repo); err != nil { log.Error("NotifyRepoPendingTransfer: %v", err) } } diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index be71d18fd..0eb2099a2 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -7,7 +7,6 @@ package webhook import ( "fmt" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" @@ -502,6 +501,44 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *is } } +func (m *webhookNotifier) NotifyNewWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { + // Add to hook queue for created wiki page. + if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventWiki, &api.WikiPayload{ + Action: api.HookWikiCreated, + Repository: convert.ToRepo(repo, perm.AccessModeOwner), + Sender: convert.ToUser(doer, nil), + Page: page, + Comment: comment, + }); err != nil { + log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err) + } +} + +func (m *webhookNotifier) NotifyEditWikiPage(doer *user_model.User, repo *repo_model.Repository, page, comment string) { + // Add to hook queue for edit wiki page. + if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventWiki, &api.WikiPayload{ + Action: api.HookWikiEdited, + Repository: convert.ToRepo(repo, perm.AccessModeOwner), + Sender: convert.ToUser(doer, nil), + Page: page, + Comment: comment, + }); err != nil { + log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err) + } +} + +func (m *webhookNotifier) NotifyDeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, page string) { + // Add to hook queue for edit wiki page. + if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventWiki, &api.WikiPayload{ + Action: api.HookWikiDeleted, + Repository: convert.ToRepo(repo, perm.AccessModeOwner), + Sender: convert.ToUser(doer, nil), + Page: page, + }); err != nil { + log.Error("PrepareWebhooks [repo_id: %d]: %v", repo.ID, err) + } +} + func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, addedLabels, removedLabels []*issues_model.Label, ) { @@ -797,7 +834,7 @@ func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *repo_mo } } -func sendReleaseHook(doer *user_model.User, rel *models.Release, action api.HookReleaseAction) { +func sendReleaseHook(doer *user_model.User, rel *repo_model.Release, action api.HookReleaseAction) { if err := rel.LoadAttributes(); err != nil { log.Error("LoadAttributes: %v", err) return @@ -814,15 +851,15 @@ func sendReleaseHook(doer *user_model.User, rel *models.Release, action api.Hook } } -func (m *webhookNotifier) NotifyNewRelease(rel *models.Release) { +func (m *webhookNotifier) NotifyNewRelease(rel *repo_model.Release) { sendReleaseHook(rel.Publisher, rel, api.HookReleasePublished) } -func (m *webhookNotifier) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { +func (m *webhookNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { sendReleaseHook(doer, rel, api.HookReleaseUpdated) } -func (m *webhookNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { +func (m *webhookNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { sendReleaseHook(doer, rel, api.HookReleaseDeleted) } diff --git a/modules/options/base.go b/modules/options/base.go new file mode 100644 index 000000000..e1d6efa7f --- /dev/null +++ b/modules/options/base.go @@ -0,0 +1,40 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package options + +import ( + "fmt" + "io/fs" + "os" + "path/filepath" + + "code.gitea.io/gitea/modules/util" +) + +func walkAssetDir(root string, callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { + // name is the path relative to the root + name := path[len(root):] + if len(name) > 0 && name[0] == '/' { + name = name[1:] + } + if err != nil { + if os.IsNotExist(err) { + return callback(path, name, d, err) + } + return err + } + if util.CommonSkip(d.Name()) { + if d.IsDir() { + return fs.SkipDir + } + return nil + } + return callback(path, name, d, err) + }); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("unable to get files for assets in %s: %w", root, err) + } + return nil +} diff --git a/modules/options/dynamic.go b/modules/options/dynamic.go index 5fea337e4..eeef11e8d 100644 --- a/modules/options/dynamic.go +++ b/modules/options/dynamic.go @@ -8,8 +8,10 @@ package options import ( "fmt" + "io/fs" "os" "path" + "path/filepath" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -45,7 +47,7 @@ func Dir(name string) ([]string, error) { isDir, err = util.IsDir(staticDir) if err != nil { - return []string{}, fmt.Errorf("Unabe to check if static directory %s is a directory. %v", staticDir, err) + return []string{}, fmt.Errorf("unable to check if static directory %s is a directory. %v", staticDir, err) } if isDir { files, err := util.StatDir(staticDir, true) @@ -64,6 +66,18 @@ func Locale(name string) ([]byte, error) { return fileFromDir(path.Join("locale", name)) } +// WalkLocales reads the content of a specific locale from static or custom path. +func WalkLocales(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.StaticRootPath, "options", "locale"), callback); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to walk locales. Error: %w", err) + } + + if err := walkAssetDir(filepath.Join(setting.CustomPath, "options", "locale"), callback); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to walk locales. Error: %w", err) + } + return nil +} + // Readme reads the content of a specific readme from static or custom path. func Readme(name string) ([]byte, error) { return fileFromDir(path.Join("readme", name)) diff --git a/modules/options/static.go b/modules/options/static.go index 6cad88cb6..d9a6c8366 100644 --- a/modules/options/static.go +++ b/modules/options/static.go @@ -9,8 +9,10 @@ package options import ( "fmt" "io" + "io/fs" "os" "path" + "path/filepath" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -74,6 +76,14 @@ func Locale(name string) ([]byte, error) { return fileFromDir(path.Join("locale", name)) } +// WalkLocales reads the content of a specific locale from static or custom path. +func WalkLocales(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.CustomPath, "options", "locale"), callback); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to walk locales. Error: %w", err) + } + return nil +} + // Readme reads the content of a specific readme from bindata or custom path. func Readme(name string) ([]byte, error) { return fileFromDir(path.Join("readme", name)) diff --git a/modules/packages/vagrant/metadata.go b/modules/packages/vagrant/metadata.go new file mode 100644 index 000000000..278dfab32 --- /dev/null +++ b/modules/packages/vagrant/metadata.go @@ -0,0 +1,97 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package vagrant + +import ( + "archive/tar" + "compress/gzip" + "io" + "strings" + + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/validation" +) + +const ( + PropertyProvider = "vagrant.provider" +) + +// Metadata represents the metadata of a Vagrant package +type Metadata struct { + Author string `json:"author,omitempty"` + Description string `json:"description,omitempty"` + ProjectURL string `json:"project_url,omitempty"` + RepositoryURL string `json:"repository_url,omitempty"` +} + +// ParseMetadataFromBox parses the metdata of a box file +func ParseMetadataFromBox(r io.Reader) (*Metadata, error) { + gzr, err := gzip.NewReader(r) + if err != nil { + return nil, err + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + for { + hd, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + + if hd.Typeflag != tar.TypeReg { + continue + } + + if hd.Name == "info.json" { + return ParseInfoFile(tr) + } + } + + return &Metadata{}, nil +} + +// ParseInfoFile parses a info.json file to retrieve the metadata of a Vagrant package +func ParseInfoFile(r io.Reader) (*Metadata, error) { + var values map[string]string + if err := json.NewDecoder(r).Decode(&values); err != nil { + return nil, err + } + + m := &Metadata{} + + // There is no defined format for this file, just try the common keys + for k, v := range values { + switch strings.ToLower(k) { + case "description": + fallthrough + case "short_description": + m.Description = v + case "website": + fallthrough + case "homepage": + fallthrough + case "url": + if validation.IsValidURL(v) { + m.ProjectURL = v + } + case "repository": + fallthrough + case "source": + if validation.IsValidURL(v) { + m.RepositoryURL = v + } + case "author": + fallthrough + case "authors": + m.Author = v + } + } + + return m, nil +} diff --git a/modules/packages/vagrant/metadata_test.go b/modules/packages/vagrant/metadata_test.go new file mode 100644 index 000000000..9720c945a --- /dev/null +++ b/modules/packages/vagrant/metadata_test.go @@ -0,0 +1,111 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package vagrant + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "io" + "testing" + + "code.gitea.io/gitea/modules/json" + + "github.com/stretchr/testify/assert" +) + +const ( + author = "gitea" + description = "Package Description" + projectURL = "https://gitea.io" + repositoryURL = "https://gitea.io/gitea/gitea" +) + +func TestParseMetadataFromBox(t *testing.T) { + createArchive := func(files map[string][]byte) io.Reader { + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + tw := tar.NewWriter(zw) + for filename, content := range files { + hdr := &tar.Header{ + Name: filename, + Mode: 0o600, + Size: int64(len(content)), + } + tw.WriteHeader(hdr) + tw.Write(content) + } + tw.Close() + zw.Close() + return &buf + } + + t.Run("MissingInfoFile", func(t *testing.T) { + data := createArchive(map[string][]byte{"dummy.txt": {}}) + + metadata, err := ParseMetadataFromBox(data) + assert.NotNil(t, metadata) + assert.NoError(t, err) + }) + + t.Run("Valid", func(t *testing.T) { + content, err := json.Marshal(map[string]string{ + "description": description, + "author": author, + "website": projectURL, + "repository": repositoryURL, + }) + assert.NoError(t, err) + + data := createArchive(map[string][]byte{"info.json": content}) + + metadata, err := ParseMetadataFromBox(data) + assert.NotNil(t, metadata) + assert.NoError(t, err) + + assert.Equal(t, author, metadata.Author) + assert.Equal(t, description, metadata.Description) + assert.Equal(t, projectURL, metadata.ProjectURL) + assert.Equal(t, repositoryURL, metadata.RepositoryURL) + }) +} + +func TestParseInfoFile(t *testing.T) { + t.Run("UnknownKeys", func(t *testing.T) { + content, err := json.Marshal(map[string]string{ + "package": "", + "dummy": "", + }) + assert.NoError(t, err) + + metadata, err := ParseInfoFile(bytes.NewReader(content)) + assert.NotNil(t, metadata) + assert.NoError(t, err) + + assert.Empty(t, metadata.Author) + assert.Empty(t, metadata.Description) + assert.Empty(t, metadata.ProjectURL) + assert.Empty(t, metadata.RepositoryURL) + }) + + t.Run("Valid", func(t *testing.T) { + content, err := json.Marshal(map[string]string{ + "description": description, + "author": author, + "website": projectURL, + "repository": repositoryURL, + }) + assert.NoError(t, err) + + metadata, err := ParseInfoFile(bytes.NewReader(content)) + assert.NotNil(t, metadata) + assert.NoError(t, err) + + assert.Equal(t, author, metadata.Author) + assert.Equal(t, description, metadata.Description) + assert.Equal(t, projectURL, metadata.ProjectURL) + assert.Equal(t, repositoryURL, metadata.RepositoryURL) + }) +} diff --git a/modules/pprof/pprof.go b/modules/pprof/pprof.go index f08072876..8ce0ad484 100644 --- a/modules/pprof/pprof.go +++ b/modules/pprof/pprof.go @@ -25,7 +25,7 @@ func DumpMemProfileForUsername(pprofDataPath, username string) error { } // DumpCPUProfileForUsername dumps a CPU profile at pprofDataPath as cpuprofile__ -// it returns the stop function which stops, writes and closes the CPU profile file +// the stop function it returns stops, writes and closes the CPU profile file func DumpCPUProfileForUsername(pprofDataPath, username string) (func(), error) { f, err := os.CreateTemp(pprofDataPath, fmt.Sprintf("cpuprofile_%s_", username)) if err != nil { diff --git a/modules/private/internal.go b/modules/private/internal.go index a77a99062..2ea516ba8 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/proxyprotocol" "code.gitea.io/gitea/modules/setting" ) @@ -50,7 +51,32 @@ func newInternalRequest(ctx context.Context, url, method string) *httplib.Reques req.SetTransport(&http.Transport{ DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { var d net.Dialer - return d.DialContext(ctx, "unix", setting.HTTPAddr) + conn, err := d.DialContext(ctx, "unix", setting.HTTPAddr) + if err != nil { + return conn, err + } + if setting.LocalUseProxyProtocol { + if err = proxyprotocol.WriteLocalHeader(conn); err != nil { + _ = conn.Close() + return nil, err + } + } + return conn, err + }, + }) + } else if setting.LocalUseProxyProtocol { + req.SetTransport(&http.Transport{ + DialContext: func(ctx context.Context, network, address string) (net.Conn, error) { + var d net.Dialer + conn, err := d.DialContext(ctx, network, address) + if err != nil { + return conn, err + } + if err = proxyprotocol.WriteLocalHeader(conn); err != nil { + _ = conn.Close() + return nil, err + } + return conn, err }, }) } diff --git a/modules/proxyprotocol/conn.go b/modules/proxyprotocol/conn.go new file mode 100644 index 000000000..10333b204 --- /dev/null +++ b/modules/proxyprotocol/conn.go @@ -0,0 +1,506 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package proxyprotocol + +import ( + "bufio" + "bytes" + "encoding/binary" + "io" + "net" + "strconv" + "strings" + "sync" + "time" + + "code.gitea.io/gitea/modules/log" +) + +var ( + // v1Prefix is the string we look for at the start of a connection + // to check if this connection is using the proxy protocol + v1Prefix = []byte("PROXY ") + v1PrefixLen = len(v1Prefix) + v2Prefix = []byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A") + v2PrefixLen = len(v2Prefix) +) + +// Conn is used to wrap and underlying connection which is speaking the +// Proxy Protocol. RemoteAddr() will return the address of the client +// instead of the proxy address. +type Conn struct { + bufReader *bufio.Reader + conn net.Conn + localAddr net.Addr + remoteAddr net.Addr + once sync.Once + proxyHeaderTimeout time.Duration + acceptUnknown bool +} + +// NewConn is used to wrap a net.Conn speaking the proxy protocol into +// a proxyprotocol.Conn +func NewConn(conn net.Conn, timeout time.Duration) *Conn { + pConn := &Conn{ + bufReader: bufio.NewReader(conn), + conn: conn, + proxyHeaderTimeout: timeout, + } + return pConn +} + +// Read reads data from the connection. +// It will initially read the proxy protocol header. +// If there is an error parsing the header, it is returned and the socket is closed. +func (p *Conn) Read(b []byte) (int, error) { + if err := p.readProxyHeaderOnce(); err != nil { + return 0, err + } + return p.bufReader.Read(b) +} + +// ReadFrom reads data from a provided reader and copies it to the connection. +func (p *Conn) ReadFrom(r io.Reader) (int64, error) { + if err := p.readProxyHeaderOnce(); err != nil { + return 0, err + } + if rf, ok := p.conn.(io.ReaderFrom); ok { + return rf.ReadFrom(r) + } + return io.Copy(p.conn, r) +} + +// WriteTo reads data from the connection and writes it to the writer. +// It will initially read the proxy protocol header. +// If there is an error parsing the header, it is returned and the socket is closed. +func (p *Conn) WriteTo(w io.Writer) (int64, error) { + if err := p.readProxyHeaderOnce(); err != nil { + return 0, err + } + return p.bufReader.WriteTo(w) +} + +// Write writes data to the connection. +// Write can be made to time out and return an error after a fixed +// time limit; see SetDeadline and SetWriteDeadline. +func (p *Conn) Write(b []byte) (int, error) { + if err := p.readProxyHeaderOnce(); err != nil { + return 0, err + } + return p.conn.Write(b) +} + +// Close closes the connection. +// Any blocked Read or Write operations will be unblocked and return errors. +func (p *Conn) Close() error { + return p.conn.Close() +} + +// LocalAddr returns the local network address. +func (p *Conn) LocalAddr() net.Addr { + _ = p.readProxyHeaderOnce() + if p.localAddr != nil { + return p.localAddr + } + return p.conn.LocalAddr() +} + +// RemoteAddr returns the address of the client if the proxy +// protocol is being used, otherwise just returns the address of +// the socket peer. If there is an error parsing the header, the +// address of the client is not returned, and the socket is closed. +// One implication of this is that the call could block if the +// client is slow. Using a Deadline is recommended if this is called +// before Read() +func (p *Conn) RemoteAddr() net.Addr { + _ = p.readProxyHeaderOnce() + if p.remoteAddr != nil { + return p.remoteAddr + } + return p.conn.RemoteAddr() +} + +// SetDeadline sets the read and write deadlines associated +// with the connection. It is equivalent to calling both +// SetReadDeadline and SetWriteDeadline. +// +// A deadline is an absolute time after which I/O operations +// fail instead of blocking. The deadline applies to all future +// and pending I/O, not just the immediately following call to +// Read or Write. After a deadline has been exceeded, the +// connection can be refreshed by setting a deadline in the future. +// +// If the deadline is exceeded a call to Read or Write or to other +// I/O methods will return an error that wraps os.ErrDeadlineExceeded. +// This can be tested using errors.Is(err, os.ErrDeadlineExceeded). +// The error's Timeout method will return true, but note that there +// are other possible errors for which the Timeout method will +// return true even if the deadline has not been exceeded. +// +// An idle timeout can be implemented by repeatedly extending +// the deadline after successful Read or Write calls. +// +// A zero value for t means I/O operations will not time out. +func (p *Conn) SetDeadline(t time.Time) error { + return p.conn.SetDeadline(t) +} + +// SetReadDeadline sets the deadline for future Read calls +// and any currently-blocked Read call. +// A zero value for t means Read will not time out. +func (p *Conn) SetReadDeadline(t time.Time) error { + return p.conn.SetReadDeadline(t) +} + +// SetWriteDeadline sets the deadline for future Write calls +// and any currently-blocked Write call. +// Even if write times out, it may return n > 0, indicating that +// some of the data was successfully written. +// A zero value for t means Write will not time out. +func (p *Conn) SetWriteDeadline(t time.Time) error { + return p.conn.SetWriteDeadline(t) +} + +// readProxyHeaderOnce will ensure that the proxy header has been read +func (p *Conn) readProxyHeaderOnce() (err error) { + p.once.Do(func() { + if err = p.readProxyHeader(); err != nil && err != io.EOF { + log.Error("Failed to read proxy prefix: %v", err) + p.Close() + p.bufReader = bufio.NewReader(p.conn) + } + }) + return err +} + +func (p *Conn) readProxyHeader() error { + if p.proxyHeaderTimeout != 0 { + readDeadLine := time.Now().Add(p.proxyHeaderTimeout) + _ = p.conn.SetReadDeadline(readDeadLine) + defer func() { + _ = p.conn.SetReadDeadline(time.Time{}) + }() + } + + inp, err := p.bufReader.Peek(v1PrefixLen) + if err != nil { + return err + } + + if bytes.Equal(inp, v1Prefix) { + return p.readV1ProxyHeader() + } + + inp, err = p.bufReader.Peek(v2PrefixLen) + if err != nil { + return err + } + if bytes.Equal(inp, v2Prefix) { + return p.readV2ProxyHeader() + } + + return &ErrBadHeader{inp} +} + +func (p *Conn) readV2ProxyHeader() error { + // The binary header format starts with a constant 12 bytes block containing the + // protocol signature : + // + // \x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A + // + // Note that this block contains a null byte at the 5th position, so it must not + // be handled as a null-terminated string. + + if _, err := p.bufReader.Discard(v2PrefixLen); err != nil { + // This shouldn't happen as we have already asserted that there should be enough in the buffer + return err + } + + // The next byte (the 13th one) is the protocol version and command. + version, err := p.bufReader.ReadByte() + if err != nil { + return err + } + + // The 14th byte contains the transport protocol and address family.otocol. + familyByte, err := p.bufReader.ReadByte() + if err != nil { + return err + } + + // The 15th and 16th bytes is the address length in bytes in network endian order. + var addressLen uint16 + if err := binary.Read(p.bufReader, binary.BigEndian, &addressLen); err != nil { + return err + } + + // Now handle the version byte: (14th byte). + // The highest four bits contains the version. As of this specification, it must + // always be sent as \x2 and the receiver must only accept this value. + if version>>4 != 0x2 { + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + + // The lowest four bits represents the command : + switch version & 0xf { + case 0x0: + // - \x0 : LOCAL : the connection was established on purpose by the proxy + // without being relayed. The connection endpoints are the sender and the + // receiver. Such connections exist when the proxy sends health-checks to the + // server. The receiver must accept this connection as valid and must use the + // real connection endpoints and discard the protocol block including the + // family which is ignored. + + // We therefore ignore the 14th, 15th and 16th bytes + p.remoteAddr = p.conn.LocalAddr() + p.localAddr = p.conn.RemoteAddr() + return nil + case 0x1: + // - \x1 : PROXY : the connection was established on behalf of another node, + // and reflects the original connection endpoints. The receiver must then use + // the information provided in the protocol block to get original the address. + default: + // - other values are unassigned and must not be emitted by senders. Receivers + // must drop connections presenting unexpected values here. + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + + // Now handle the familyByte byte: (15th byte). + // The highest 4 bits contain the address family, the lowest 4 bits contain the protocol + + // The address family maps to the original socket family without necessarily + // matching the values internally used by the system. It may be one of : + // + // - 0x0 : AF_UNSPEC : the connection is forwarded for an unknown, unspecified + // or unsupported protocol. The sender should use this family when sending + // LOCAL commands or when dealing with unsupported protocol families. The + // receiver is free to accept the connection anyway and use the real endpoint + // addresses or to reject it. The receiver should ignore address information. + // + // - 0x1 : AF_INET : the forwarded connection uses the AF_INET address family + // (IPv4). The addresses are exactly 4 bytes each in network byte order, + // followed by transport protocol information (typically ports). + // + // - 0x2 : AF_INET6 : the forwarded connection uses the AF_INET6 address family + // (IPv6). The addresses are exactly 16 bytes each in network byte order, + // followed by transport protocol information (typically ports). + // + // - 0x3 : AF_UNIX : the forwarded connection uses the AF_UNIX address family + // (UNIX). The addresses are exactly 108 bytes each. + // + // - other values are unspecified and must not be emitted in version 2 of this + // protocol and must be rejected as invalid by receivers. + + // The transport protocol is specified in the lowest 4 bits of the 14th byte : + // + // - 0x0 : UNSPEC : the connection is forwarded for an unknown, unspecified + // or unsupported protocol. The sender should use this family when sending + // LOCAL commands or when dealing with unsupported protocol families. The + // receiver is free to accept the connection anyway and use the real endpoint + // addresses or to reject it. The receiver should ignore address information. + // + // - 0x1 : STREAM : the forwarded connection uses a SOCK_STREAM protocol (eg: + // TCP or UNIX_STREAM). When used with AF_INET/AF_INET6 (TCP), the addresses + // are followed by the source and destination ports represented on 2 bytes + // each in network byte order. + // + // - 0x2 : DGRAM : the forwarded connection uses a SOCK_DGRAM protocol (eg: + // UDP or UNIX_DGRAM). When used with AF_INET/AF_INET6 (UDP), the addresses + // are followed by the source and destination ports represented on 2 bytes + // each in network byte order. + // + // - other values are unspecified and must not be emitted in version 2 of this + // protocol and must be rejected as invalid by receivers. + + if familyByte>>4 == 0x0 || familyByte&0xf == 0x0 { + // - hi 0x0 : AF_UNSPEC : the connection is forwarded for an unknown address type + // or + // - lo 0x0 : UNSPEC : the connection is forwarded for an unspecified protocol + if !p.acceptUnknown { + p.conn.Close() + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + p.remoteAddr = p.conn.LocalAddr() + p.localAddr = p.conn.RemoteAddr() + _, err = p.bufReader.Discard(int(addressLen)) + return err + } + + // other address or protocol + if (familyByte>>4) > 0x3 || (familyByte&0xf) > 0x2 { + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + + // Handle AF_UNIX addresses + if familyByte>>4 == 0x3 { + // - \x31 : UNIX stream : the forwarded connection uses SOCK_STREAM over the + // AF_UNIX protocol family. Address length is 2*108 = 216 bytes. + // - \x32 : UNIX datagram : the forwarded connection uses SOCK_DGRAM over the + // AF_UNIX protocol family. Address length is 2*108 = 216 bytes. + if addressLen != 216 { + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + remoteName := make([]byte, 108) + localName := make([]byte, 108) + if _, err := p.bufReader.Read(remoteName); err != nil { + return err + } + if _, err := p.bufReader.Read(localName); err != nil { + return err + } + protocol := "unix" + if familyByte&0xf == 2 { + protocol = "unixgram" + } + + p.remoteAddr = &net.UnixAddr{ + Name: string(remoteName), + Net: protocol, + } + p.localAddr = &net.UnixAddr{ + Name: string(localName), + Net: protocol, + } + return nil + } + + var remoteIP []byte + var localIP []byte + var remotePort uint16 + var localPort uint16 + + if familyByte>>4 == 0x1 { + // AF_INET + // - \x11 : TCP over IPv4 : the forwarded connection uses TCP over the AF_INET + // protocol family. Address length is 2*4 + 2*2 = 12 bytes. + // - \x12 : UDP over IPv4 : the forwarded connection uses UDP over the AF_INET + // protocol family. Address length is 2*4 + 2*2 = 12 bytes. + if addressLen != 12 { + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + + remoteIP = make([]byte, 4) + localIP = make([]byte, 4) + } else { + // AF_INET6 + // - \x21 : TCP over IPv6 : the forwarded connection uses TCP over the AF_INET6 + // protocol family. Address length is 2*16 + 2*2 = 36 bytes. + // - \x22 : UDP over IPv6 : the forwarded connection uses UDP over the AF_INET6 + // protocol family. Address length is 2*16 + 2*2 = 36 bytes. + if addressLen != 36 { + return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))} + } + + remoteIP = make([]byte, 16) + localIP = make([]byte, 16) + } + + if _, err := p.bufReader.Read(remoteIP); err != nil { + return err + } + if _, err := p.bufReader.Read(localIP); err != nil { + return err + } + if err := binary.Read(p.bufReader, binary.BigEndian, &remotePort); err != nil { + return err + } + if err := binary.Read(p.bufReader, binary.BigEndian, &localPort); err != nil { + return err + } + + if familyByte&0xf == 1 { + p.remoteAddr = &net.TCPAddr{ + IP: remoteIP, + Port: int(remotePort), + } + p.localAddr = &net.TCPAddr{ + IP: localIP, + Port: int(localPort), + } + } else { + p.remoteAddr = &net.UDPAddr{ + IP: remoteIP, + Port: int(remotePort), + } + p.localAddr = &net.UDPAddr{ + IP: localIP, + Port: int(localPort), + } + } + return nil +} + +func (p *Conn) readV1ProxyHeader() error { + // Read until a newline + header, err := p.bufReader.ReadString('\n') + if err != nil { + p.conn.Close() + return err + } + + if header[len(header)-2] != '\r' { + return &ErrBadHeader{[]byte(header)} + } + + // Strip the carriage return and new line + header = header[:len(header)-2] + + // Split on spaces, should be (PROXY ) + parts := strings.Split(header, " ") + if len(parts) < 2 { + p.conn.Close() + return &ErrBadHeader{[]byte(header)} + } + + // Verify the type is known + switch parts[1] { + case "UNKNOWN": + if !p.acceptUnknown || len(parts) != 2 { + p.conn.Close() + return &ErrBadHeader{[]byte(header)} + } + p.remoteAddr = p.conn.LocalAddr() + p.localAddr = p.conn.RemoteAddr() + return nil + case "TCP4": + case "TCP6": + default: + p.conn.Close() + return &ErrBadAddressType{parts[1]} + } + + if len(parts) != 6 { + p.conn.Close() + return &ErrBadHeader{[]byte(header)} + } + + // Parse out the remote address + ip := net.ParseIP(parts[2]) + if ip == nil { + p.conn.Close() + return &ErrBadRemote{parts[2], parts[4]} + } + port, err := strconv.Atoi(parts[4]) + if err != nil { + p.conn.Close() + return &ErrBadRemote{parts[2], parts[4]} + } + p.remoteAddr = &net.TCPAddr{IP: ip, Port: port} + + // Parse out the destination address + ip = net.ParseIP(parts[3]) + if ip == nil { + p.conn.Close() + return &ErrBadLocal{parts[3], parts[5]} + } + port, err = strconv.Atoi(parts[5]) + if err != nil { + p.conn.Close() + return &ErrBadLocal{parts[3], parts[5]} + } + p.localAddr = &net.TCPAddr{IP: ip, Port: port} + + return nil +} diff --git a/modules/proxyprotocol/errors.go b/modules/proxyprotocol/errors.go new file mode 100644 index 000000000..2acf9d84b --- /dev/null +++ b/modules/proxyprotocol/errors.go @@ -0,0 +1,45 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package proxyprotocol + +import "fmt" + +// ErrBadHeader is an error demonstrating a bad proxy header +type ErrBadHeader struct { + Header []byte +} + +func (e *ErrBadHeader) Error() string { + return fmt.Sprintf("Unexpected proxy header: %v", e.Header) +} + +// ErrBadAddressType is an error demonstrating a bad proxy header with bad Address type +type ErrBadAddressType struct { + Address string +} + +func (e *ErrBadAddressType) Error() string { + return fmt.Sprintf("Unexpected proxy header address type: %s", e.Address) +} + +// ErrBadRemote is an error demonstrating a bad proxy header with bad Remote +type ErrBadRemote struct { + IP string + Port string +} + +func (e *ErrBadRemote) Error() string { + return fmt.Sprintf("Unexpected proxy header remote IP and port: %s %s", e.IP, e.Port) +} + +// ErrBadLocal is an error demonstrating a bad proxy header with bad Local +type ErrBadLocal struct { + IP string + Port string +} + +func (e *ErrBadLocal) Error() string { + return fmt.Sprintf("Unexpected proxy header local IP and port: %s %s", e.IP, e.Port) +} diff --git a/modules/proxyprotocol/listener.go b/modules/proxyprotocol/listener.go new file mode 100644 index 000000000..64d9b323e --- /dev/null +++ b/modules/proxyprotocol/listener.go @@ -0,0 +1,47 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package proxyprotocol + +import ( + "net" + "time" +) + +// Listener is used to wrap an underlying listener, +// whose connections may be using the HAProxy Proxy Protocol (version 1 or 2). +// If the connection is using the protocol, the RemoteAddr() will return +// the correct client address. +// +// Optionally define ProxyHeaderTimeout to set a maximum time to +// receive the Proxy Protocol Header. Zero means no timeout. +type Listener struct { + Listener net.Listener + ProxyHeaderTimeout time.Duration + AcceptUnknown bool // allow PROXY UNKNOWN +} + +// Accept implements the Accept method in the Listener interface +// it waits for the next call and returns a wrapped Conn. +func (p *Listener) Accept() (net.Conn, error) { + // Get the underlying connection + conn, err := p.Listener.Accept() + if err != nil { + return nil, err + } + + newConn := NewConn(conn, p.ProxyHeaderTimeout) + newConn.acceptUnknown = p.AcceptUnknown + return newConn, nil +} + +// Close closes the underlying listener. +func (p *Listener) Close() error { + return p.Listener.Close() +} + +// Addr returns the underlying listener's network address. +func (p *Listener) Addr() net.Addr { + return p.Listener.Addr() +} diff --git a/modules/proxyprotocol/util.go b/modules/proxyprotocol/util.go new file mode 100644 index 000000000..b12771b68 --- /dev/null +++ b/modules/proxyprotocol/util.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package proxyprotocol + +import "io" + +var localHeader = append(v2Prefix, '\x20', '\x00', '\x00', '\x00', '\x00') + +// WriteLocalHeader will write the ProxyProtocol Header for a local connection to the provided writer +func WriteLocalHeader(w io.Writer) error { + _, err := w.Write(localHeader) + return err +} diff --git a/modules/queue/queue_disk_channel_test.go b/modules/queue/queue_disk_channel_test.go index 22b4f0f45..b1820e73a 100644 --- a/modules/queue/queue_disk_channel_test.go +++ b/modules/queue/queue_disk_channel_test.go @@ -5,13 +5,11 @@ package queue import ( - "os" "sync" "testing" "time" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) @@ -33,9 +31,7 @@ func TestPersistableChannelQueue(t *testing.T) { queueShutdown := []func(){} queueTerminate := []func(){} - tmpDir, err := os.MkdirTemp("", "persistable-channel-queue-test-data") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() queue, err := NewPersistableChannelQueue(handle, PersistableChannelQueueConfiguration{ DataDir: tmpDir, @@ -223,9 +219,7 @@ func TestPersistableChannelQueue_Pause(t *testing.T) { queueTerminate := []func(){} terminated := make(chan struct{}) - tmpDir, err := os.MkdirTemp("", "persistable-channel-queue-pause-test-data") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() queue, err = NewPersistableChannelQueue(handle, PersistableChannelQueueConfiguration{ DataDir: tmpDir, diff --git a/modules/queue/queue_disk_test.go b/modules/queue/queue_disk_test.go index d2d8e135c..b0835c896 100644 --- a/modules/queue/queue_disk_test.go +++ b/modules/queue/queue_disk_test.go @@ -5,13 +5,10 @@ package queue import ( - "os" "sync" "testing" "time" - "code.gitea.io/gitea/modules/util" - "github.com/stretchr/testify/assert" ) @@ -30,9 +27,7 @@ func TestLevelQueue(t *testing.T) { queueShutdown := []func(){} queueTerminate := []func(){} - tmpDir, err := os.MkdirTemp("", "level-queue-test-data") - assert.NoError(t, err) - defer util.RemoveAll(tmpDir) + tmpDir := t.TempDir() queue, err := NewLevelQueue(handle, LevelQueueConfiguration{ ByteFIFOQueueConfiguration: ByteFIFOQueueConfiguration{ diff --git a/modules/repository/collaborator.go b/modules/repository/collaborator.go new file mode 100644 index 000000000..9d20a2589 --- /dev/null +++ b/modules/repository/collaborator.go @@ -0,0 +1,43 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "context" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" + access_model "code.gitea.io/gitea/models/perm/access" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" +) + +func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { + collaboration := &repo_model.Collaboration{ + RepoID: repo.ID, + UserID: u.ID, + } + + has, err := db.GetByBean(ctx, collaboration) + if err != nil { + return err + } else if has { + return nil + } + collaboration.Mode = perm.AccessModeWrite + + if err = db.Insert(ctx, collaboration); err != nil { + return err + } + + return access_model.RecalculateUserAccess(ctx, repo, u.ID) +} + +// AddCollaborator adds new collaboration to a repository with default access mode. +func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error { + return db.WithTx(func(ctx context.Context) error { + return addCollaborator(ctx, repo, u) + }) +} diff --git a/modules/repository/collaborator_test.go b/modules/repository/collaborator_test.go new file mode 100644 index 000000000..1b927aa3b --- /dev/null +++ b/modules/repository/collaborator_test.go @@ -0,0 +1,281 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/organization" + perm_model "code.gitea.io/gitea/models/perm" + access_model "code.gitea.io/gitea/models/perm/access" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + + "github.com/stretchr/testify/assert" +) + +func TestRepository_AddCollaborator(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + testSuccess := func(repoID, userID int64) { + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) + assert.NoError(t, repo.GetOwner(db.DefaultContext)) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) + assert.NoError(t, AddCollaborator(repo, user)) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) + } + testSuccess(1, 4) + testSuccess(1, 4) + testSuccess(3, 4) +} + +func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + // public non-organization repo + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + assert.NoError(t, repo.LoadUnits(db.DefaultContext)) + + // plain user + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // change to collaborator + assert.NoError(t, AddCollaborator(repo, user)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // collaborator + collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // owner + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // admin + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } +} + +func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + // private non-organization repo + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + assert.NoError(t, repo.LoadUnits(db.DefaultContext)) + + // plain user + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.False(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // change to collaborator to default write access + assert.NoError(t, AddCollaborator(repo, user)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // owner + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // admin + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } +} + +func TestRepoPermissionPublicOrgRepo(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + // public organization repo + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) + assert.NoError(t, repo.LoadUnits(db.DefaultContext)) + + // plain user + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // change to collaborator to default write access + assert.NoError(t, AddCollaborator(repo, user)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // org member team owner + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // org member team tester + member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + } + assert.True(t, perm.CanWrite(unit.TypeIssues)) + assert.False(t, perm.CanWrite(unit.TypeCode)) + + // admin + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } +} + +func TestRepoPermissionPrivateOrgRepo(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + // private organization repo + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) + assert.NoError(t, repo.LoadUnits(db.DefaultContext)) + + // plain user + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.False(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // change to collaborator to default write access + assert.NoError(t, AddCollaborator(repo, user)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.False(t, perm.CanWrite(unit.Type)) + } + + // org member team owner + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // update team information and then check permission + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) + err = organization.UpdateTeamUnits(team, nil) + assert.NoError(t, err) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } + + // org member team tester + tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) + assert.NoError(t, err) + assert.True(t, perm.CanWrite(unit.TypeIssues)) + assert.False(t, perm.CanWrite(unit.TypeCode)) + assert.False(t, perm.CanRead(unit.TypeCode)) + + // org member team reviewer + reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) + assert.NoError(t, err) + assert.False(t, perm.CanRead(unit.TypeIssues)) + assert.False(t, perm.CanWrite(unit.TypeCode)) + assert.True(t, perm.CanRead(unit.TypeCode)) + + // admin + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) + assert.NoError(t, err) + for _, unit := range repo.Units { + assert.True(t, perm.CanRead(unit.Type)) + assert.True(t, perm.CanWrite(unit.Type)) + } +} diff --git a/modules/repository/create.go b/modules/repository/create.go index 9204d7e42..7a25323de 100644 --- a/modules/repository/create.go +++ b/modules/repository/create.go @@ -13,11 +13,16 @@ import ( "unicode/utf8" "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -25,8 +30,150 @@ import ( "code.gitea.io/gitea/modules/util" ) +// CreateRepositoryByExample creates a repository for the user/organization. +func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { + if err = repo_model.IsUsableRepoName(repo.Name); err != nil { + return err + } + + has, err := repo_model.IsRepositoryExist(ctx, u, repo.Name) + if err != nil { + return fmt.Errorf("IsRepositoryExist: %v", err) + } else if has { + return repo_model.ErrRepoAlreadyExist{ + Uname: u.Name, + Name: repo.Name, + } + } + + repoPath := repo_model.RepoPath(u.Name, repo.Name) + isExist, err := util.IsExist(repoPath) + if err != nil { + log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + return err + } + if !overwriteOrAdopt && isExist { + log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) + return repo_model.ErrRepoFilesAlreadyExist{ + Uname: u.Name, + Name: repo.Name, + } + } + + if err = db.Insert(ctx, repo); err != nil { + return err + } + if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil { + return err + } + + // insert units for repo + units := make([]repo_model.RepoUnit, 0, len(unit.DefaultRepoUnits)) + for _, tp := range unit.DefaultRepoUnits { + if tp == unit.TypeIssues { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: tp, + Config: &repo_model.IssuesConfig{ + EnableTimetracker: setting.Service.DefaultEnableTimetracking, + AllowOnlyContributorsToTrackTime: setting.Service.DefaultAllowOnlyContributorsToTrackTime, + EnableDependencies: setting.Service.DefaultEnableDependencies, + }, + }) + } else if tp == unit.TypePullRequests { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: tp, + Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle), AllowRebaseUpdate: true}, + }) + } else { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: tp, + }) + } + } + + if err = db.Insert(ctx, units); err != nil { + return err + } + + // Remember visibility preference. + u.LastRepoVisibility = repo.IsPrivate + if err = user_model.UpdateUserCols(ctx, u, "last_repo_visibility"); err != nil { + return fmt.Errorf("UpdateUserCols: %v", err) + } + + if err = user_model.IncrUserRepoNum(ctx, u.ID); err != nil { + return fmt.Errorf("IncrUserRepoNum: %v", err) + } + u.NumRepos++ + + // Give access to all members in teams with access to all repositories. + if u.IsOrganization() { + teams, err := organization.FindOrgTeams(ctx, u.ID) + if err != nil { + return fmt.Errorf("FindOrgTeams: %v", err) + } + for _, t := range teams { + if t.IncludesAllRepositories { + if err := models.AddRepository(ctx, t, repo); err != nil { + return fmt.Errorf("AddRepository: %v", err) + } + } + } + + if isAdmin, err := access_model.IsUserRepoAdmin(ctx, repo, doer); err != nil { + return fmt.Errorf("IsUserRepoAdmin: %v", err) + } else if !isAdmin { + // Make creator repo admin if it wasn't assigned automatically + if err = addCollaborator(ctx, repo, doer); err != nil { + return fmt.Errorf("addCollaborator: %v", err) + } + if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil { + return fmt.Errorf("ChangeCollaborationAccessModeCtx: %v", err) + } + } + } else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { + // Organization automatically called this in AddRepository method. + return fmt.Errorf("RecalculateAccesses: %v", err) + } + + if setting.Service.AutoWatchNewRepos { + if err = repo_model.WatchRepo(ctx, doer.ID, repo.ID, true); err != nil { + return fmt.Errorf("WatchRepo: %v", err) + } + } + + if err = webhook.CopyDefaultWebhooksToRepo(ctx, repo.ID); err != nil { + return fmt.Errorf("CopyDefaultWebhooksToRepo: %v", err) + } + + return nil +} + +// CreateRepoOptions contains the create repository options +type CreateRepoOptions struct { + Name string + Description string + OriginalURL string + GitServiceType api.GitServiceType + Gitignores string + IssueLabels string + License string + Readme string + DefaultBranch string + IsPrivate bool + IsMirror bool + IsTemplate bool + AutoInit bool + Status repo_model.RepositoryStatus + TrustModel repo_model.TrustModelType + MirrorInterval string +} + // CreateRepository creates a repository for the user/organization. -func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { +func CreateRepository(doer, u *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) { if !doer.IsAdmin && !u.CanCreateRepo() { return nil, repo_model.ErrReachLimitOfRepo{ Limit: u.MaxRepoCreation, @@ -66,7 +213,7 @@ func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) ( var rollbackRepo *repo_model.Repository if err := db.WithTx(func(ctx context.Context) error { - if err := models.CreateRepository(ctx, doer, u, repo, false); err != nil { + if err := CreateRepositoryByExample(ctx, doer, u, repo, false); err != nil { return err } @@ -220,7 +367,7 @@ func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibili // If repo has become private, we need to set its actions to private. if repo.IsPrivate { - _, err = e.Where("repo_id = ?", repo.ID).Cols("is_private").Update(&models.Action{ + _, err = e.Where("repo_id = ?", repo.ID).Cols("is_private").Update(&activities_model.Action{ IsPrivate: true, }) if err != nil { diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index 39f8b1135..304078284 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -9,6 +9,7 @@ import ( "testing" "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" @@ -56,7 +57,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { // Create repos. repoIds := make([]int64, 0) for i := 0; i < 3; i++ { - r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) + r, err := CreateRepository(user, org.AsUser(), CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) assert.NoError(t, err, "CreateRepository %d", i) if r != nil { repoIds = append(repoIds, r.ID) @@ -118,7 +119,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } // Create repo and check teams repositories. - r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: "repo-last"}) + r, err := CreateRepository(user, org.AsUser(), CreateRepoOptions{Name: "repo-last"}) assert.NoError(t, err, "CreateRepository last") if r != nil { repoIds = append(repoIds, r.ID) @@ -162,7 +163,7 @@ func TestUpdateRepositoryVisibilityChanged(t *testing.T) { assert.NoError(t, err) // Check visibility of action has become private - act := models.Action{} + act := activities_model.Action{} _, err = db.GetEngine(db.DefaultContext).ID(3).Get(&act) assert.NoError(t, err) diff --git a/modules/repository/generate.go b/modules/repository/generate.go index 8f7b4c885..4d76d3399 100644 --- a/modules/repository/generate.go +++ b/modules/repository/generate.go @@ -15,7 +15,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -321,7 +320,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ TrustModel: templateRepo.TrustModel, } - if err = models.CreateRepository(ctx, doer, owner, generateRepo, false); err != nil { + if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false); err != nil { return nil, err } diff --git a/modules/repository/init.go b/modules/repository/init.go index e984697cd..37ed0748b 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -15,7 +15,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -214,7 +213,7 @@ func LoadRepoConfig() { Licenses = sortedLicenses } -func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts models.CreateRepoOptions) error { +func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { commitTimeStr := time.Now().Format(time.RFC3339) authorSig := repo.Owner.NewGitSig() @@ -387,7 +386,7 @@ func checkInitRepository(ctx context.Context, owner, name string) (err error) { } // InitRepository initializes README and .gitignore if needed. -func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts models.CreateRepoOptions) (err error) { +func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { if err = checkInitRepository(ctx, repo.OwnerName, repo.Name); err != nil { return err } diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 436045146..48c3edf60 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -13,7 +13,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/organization" @@ -31,8 +30,8 @@ import ( ) /* - GitHub, GitLab, Gogs: *.wiki.git - BitBucket: *.git/wiki +GitHub, GitLab, Gogs: *.wiki.git +BitBucket: *.git/wiki */ var commonWikiURLSuffixes = []string{".wiki.git", ".git/wiki"} @@ -277,14 +276,14 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) } existingRelTags := make(map[string]struct{}) - opts := models.FindReleasesOptions{ + opts := repo_model.FindReleasesOptions{ IncludeDrafts: true, IncludeTags: true, ListOptions: db.ListOptions{PageSize: 50}, } for page := 1; ; page++ { opts.Page = page - rels, err := models.GetReleasesByRepoID(repo.ID, opts) + rels, err := repo_model.GetReleasesByRepoID(repo.ID, opts) if err != nil { return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) } @@ -300,7 +299,7 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) return fmt.Errorf("unable to GetTagCommitID for %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) } if git.IsErrNotExist(err) || commitID != rel.Sha1 { - if err := models.PushUpdateDeleteTag(repo, rel.TagName); err != nil { + if err := repo_model.PushUpdateDeleteTag(repo, rel.TagName); err != nil { return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) } } else { @@ -359,7 +358,7 @@ func PushUpdateAddTag(repo *repo_model.Repository, gitRepo *git.Repository, tagN return fmt.Errorf("unable to get CommitsCount: %w", err) } - rel := models.Release{ + rel := repo_model.Release{ RepoID: repo.ID, TagName: tagName, LowerTagName: strings.ToLower(tagName), @@ -372,7 +371,7 @@ func PushUpdateAddTag(repo *repo_model.Repository, gitRepo *git.Repository, tagN rel.PublisherID = author.ID } - return models.SaveOrUpdateTag(repo, &rel) + return repo_model.SaveOrUpdateTag(repo, &rel) } // StoreMissingLfsObjectsInRepository downloads missing LFS objects @@ -489,14 +488,14 @@ func pullMirrorReleaseSync(repo *repo_model.Repository, gitRepo *git.Repository) // // clear out existing releases // - if _, err := db.DeleteByBean(ctx, &models.Release{RepoID: repo.ID}); err != nil { + if _, err := db.DeleteByBean(ctx, &repo_model.Release{RepoID: repo.ID}); err != nil { return fmt.Errorf("unable to clear releases for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) } // // make release set identical to upstream tags // for _, tag := range tags { - release := models.Release{ + release := repo_model.Release{ RepoID: repo.ID, TagName: tag.Name, LowerTagName: strings.ToLower(tag.Name), diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 3ab25fef6..09e510ffa 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -92,47 +92,56 @@ var ( // LocalURL is the url for locally running applications to contact Gitea. It always has a '/' suffix // It maps to ini:"LOCAL_ROOT_URL" LocalURL string + // AssetVersion holds a opaque value that is used for cache-busting assets + AssetVersion string // Server settings - Protocol Scheme - Domain string - HTTPAddr string - HTTPPort string - RedirectOtherPort bool - PortToRedirect string - OfflineMode bool - CertFile string - KeyFile string - StaticRootPath string - StaticCacheTime time.Duration - EnableGzip bool - LandingPageURL LandingPage - LandingPageCustom string - UnixSocketPermission uint32 - EnablePprof bool - PprofDataPath string - EnableAcme bool - AcmeTOS bool - AcmeLiveDirectory string - AcmeEmail string - AcmeURL string - AcmeCARoot string - SSLMinimumVersion string - SSLMaximumVersion string - SSLCurvePreferences []string - SSLCipherSuites []string - GracefulRestartable bool - GracefulHammerTime time.Duration - StartupTimeout time.Duration - PerWriteTimeout = 30 * time.Second - PerWritePerKbTimeout = 10 * time.Second - StaticURLPrefix string - AbsoluteAssetURL string + Protocol Scheme + UseProxyProtocol bool // `ini:"USE_PROXY_PROTOCOL"` + ProxyProtocolTLSBridging bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"` + ProxyProtocolHeaderTimeout time.Duration + ProxyProtocolAcceptUnknown bool + Domain string + HTTPAddr string + HTTPPort string + LocalUseProxyProtocol bool + RedirectOtherPort bool + RedirectorUseProxyProtocol bool + PortToRedirect string + OfflineMode bool + CertFile string + KeyFile string + StaticRootPath string + StaticCacheTime time.Duration + EnableGzip bool + LandingPageURL LandingPage + LandingPageCustom string + UnixSocketPermission uint32 + EnablePprof bool + PprofDataPath string + EnableAcme bool + AcmeTOS bool + AcmeLiveDirectory string + AcmeEmail string + AcmeURL string + AcmeCARoot string + SSLMinimumVersion string + SSLMaximumVersion string + SSLCurvePreferences []string + SSLCipherSuites []string + GracefulRestartable bool + GracefulHammerTime time.Duration + StartupTimeout time.Duration + PerWriteTimeout = 30 * time.Second + PerWritePerKbTimeout = 10 * time.Second + StaticURLPrefix string + AbsoluteAssetURL string SSH = struct { Disabled bool `ini:"DISABLE_SSH"` StartBuiltinServer bool `ini:"START_SSH_SERVER"` BuiltinServerUser string `ini:"BUILTIN_SSH_SERVER_USER"` + UseProxyProtocol bool `ini:"SSH_SERVER_USE_PROXY_PROTOCOL"` Domain string `ini:"SSH_DOMAIN"` Port int `ini:"SSH_PORT"` User string `ini:"SSH_USER"` @@ -231,6 +240,7 @@ var ( CustomEmojisMap map[string]string `ini:"-"` SearchRepoDescription bool UseServiceWorker bool + OnlyShowRelevantRepos bool Notification struct { MinTimeout time.Duration @@ -717,6 +727,10 @@ func loadFromConf(allowEmpty bool, extraConfig string) { HTTPAddr = filepath.Join(AppWorkPath, HTTPAddr) } } + UseProxyProtocol = sec.Key("USE_PROXY_PROTOCOL").MustBool(false) + ProxyProtocolTLSBridging = sec.Key("PROXY_PROTOCOL_TLS_BRIDGING").MustBool(false) + ProxyProtocolHeaderTimeout = sec.Key("PROXY_PROTOCOL_HEADER_TIMEOUT").MustDuration(5 * time.Second) + ProxyProtocolAcceptUnknown = sec.Key("PROXY_PROTOCOL_ACCEPT_UNKNOWN").MustBool(false) GracefulRestartable = sec.Key("ALLOW_GRACEFUL_RESTARTS").MustBool(true) GracefulHammerTime = sec.Key("GRACEFUL_HAMMER_TIME").MustDuration(60 * time.Second) StartupTimeout = sec.Key("STARTUP_TIMEOUT").MustDuration(0 * time.Second) @@ -748,6 +762,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) { } AbsoluteAssetURL = MakeAbsoluteAssetURL(AppURL, StaticURLPrefix) + AssetVersion = strings.ReplaceAll(AppVer, "+", "~") // make sure the version string is clear (no real escaping is needed) manifestBytes := MakeManifestData(AppName, AppURL, AbsoluteAssetURL) ManifestData = `application/json;base64,` + base64.StdEncoding.EncodeToString(manifestBytes) @@ -770,8 +785,10 @@ func loadFromConf(allowEmpty bool, extraConfig string) { } LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(defaultLocalURL) LocalURL = strings.TrimRight(LocalURL, "/") + "/" + LocalUseProxyProtocol = sec.Key("LOCAL_USE_PROXY_PROTOCOL").MustBool(UseProxyProtocol) RedirectOtherPort = sec.Key("REDIRECT_OTHER_PORT").MustBool(false) PortToRedirect = sec.Key("PORT_TO_REDIRECT").MustString("80") + RedirectorUseProxyProtocol = sec.Key("REDIRECTOR_USE_PROXY_PROTOCOL").MustBool(UseProxyProtocol) OfflineMode = sec.Key("OFFLINE_MODE").MustBool() DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool() if len(StaticRootPath) == 0 { @@ -836,6 +853,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) { SSH.KeygenPath = sec.Key("SSH_KEYGEN_PATH").MustString("ssh-keygen") SSH.Port = sec.Key("SSH_PORT").MustInt(22) SSH.ListenPort = sec.Key("SSH_LISTEN_PORT").MustInt(SSH.Port) + SSH.UseProxyProtocol = sec.Key("SSH_SERVER_USE_PROXY_PROTOCOL").MustBool(false) // When disable SSH, start builtin server value is ignored. if SSH.Disabled { @@ -1070,6 +1088,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) { UI.DefaultShowFullName = Cfg.Section("ui").Key("DEFAULT_SHOW_FULL_NAME").MustBool(false) UI.SearchRepoDescription = Cfg.Section("ui").Key("SEARCH_REPO_DESCRIPTION").MustBool(true) UI.UseServiceWorker = Cfg.Section("ui").Key("USE_SERVICE_WORKER").MustBool(false) + UI.OnlyShowRelevantRepos = Cfg.Section("ui").Key("ONLY_SHOW_RELEVANT_REPOS").MustBool(false) HasRobotsTxt, err = util.IsFile(path.Join(CustomPath, "robots.txt")) if err != nil { diff --git a/modules/ssh/init.go b/modules/ssh/init.go index f6332bb18..72cb6df7a 100644 --- a/modules/ssh/init.go +++ b/modules/ssh/init.go @@ -18,6 +18,7 @@ import ( func Init() error { if setting.SSH.Disabled { + builtinUnused() return nil } diff --git a/modules/ssh/ssh_graceful.go b/modules/ssh/ssh_graceful.go index 9b91baf09..166ea0b98 100644 --- a/modules/ssh/ssh_graceful.go +++ b/modules/ssh/ssh_graceful.go @@ -17,7 +17,7 @@ func listen(server *ssh.Server) { gracefulServer.PerWriteTimeout = setting.SSH.PerWriteTimeout gracefulServer.PerWritePerKbTimeout = setting.SSH.PerWritePerKbTimeout - err := gracefulServer.ListenAndServe(server.Serve) + err := gracefulServer.ListenAndServe(server.Serve, setting.SSH.UseProxyProtocol) if err != nil { select { case <-graceful.GetManager().IsShutdown(): diff --git a/modules/structs/hook.go b/modules/structs/hook.go index 07d51915d..132b24b85 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -397,6 +397,39 @@ type ReviewPayload struct { Content string `json:"content"` } +// __ __.__ __ .__ +// / \ / \__| | _|__| +// \ \/\/ / | |/ / | +// \ /| | <| | +// \__/\ / |__|__|_ \__| +// \/ \/ + +// HookWikiAction an action that happens to a wiki page +type HookWikiAction string + +const ( + // HookWikiCreated created + HookWikiCreated HookWikiAction = "created" + // HookWikiEdited edited + HookWikiEdited HookWikiAction = "edited" + // HookWikiDeleted deleted + HookWikiDeleted HookWikiAction = "deleted" +) + +// WikiPayload payload for repository webhooks +type WikiPayload struct { + Action HookWikiAction `json:"action"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + Page string `json:"page"` + Comment string `json:"comment"` +} + +// JSONPayload JSON representation of the payload +func (p *WikiPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + //__________ .__ __ //\______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__. // | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | | diff --git a/modules/structs/issue.go b/modules/structs/issue.go index c72487fe4..27ec81f72 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -5,7 +5,7 @@ package structs import ( - "strings" + "path/filepath" "time" ) @@ -120,19 +120,57 @@ type IssueDeadline struct { Deadline *time.Time `json:"due_date"` } +// IssueFormFieldType defines issue form field type, can be "markdown", "textarea", "input", "dropdown" or "checkboxes" +type IssueFormFieldType string + +const ( + IssueFormFieldTypeMarkdown IssueFormFieldType = "markdown" + IssueFormFieldTypeTextarea IssueFormFieldType = "textarea" + IssueFormFieldTypeInput IssueFormFieldType = "input" + IssueFormFieldTypeDropdown IssueFormFieldType = "dropdown" + IssueFormFieldTypeCheckboxes IssueFormFieldType = "checkboxes" +) + +// IssueFormField represents a form field +// swagger:model +type IssueFormField struct { + Type IssueFormFieldType `json:"type" yaml:"type"` + ID string `json:"id" yaml:"id"` + Attributes map[string]interface{} `json:"attributes" yaml:"attributes"` + Validations map[string]interface{} `json:"validations" yaml:"validations"` +} + // IssueTemplate represents an issue template for a repository // swagger:model type IssueTemplate struct { - Name string `json:"name" yaml:"name"` - Title string `json:"title" yaml:"title"` - About string `json:"about" yaml:"about"` - Labels []string `json:"labels" yaml:"labels"` - Ref string `json:"ref" yaml:"ref"` - Content string `json:"content" yaml:"-"` - FileName string `json:"file_name" yaml:"-"` + Name string `json:"name" yaml:"name"` + Title string `json:"title" yaml:"title"` + About string `json:"about" yaml:"about"` // Using "description" in a template file is compatible + Labels []string `json:"labels" yaml:"labels"` + Ref string `json:"ref" yaml:"ref"` + Content string `json:"content" yaml:"-"` + Fields []*IssueFormField `json:"body" yaml:"body"` + FileName string `json:"file_name" yaml:"-"` } -// Valid checks whether an IssueTemplate is considered valid, e.g. at least name and about -func (it IssueTemplate) Valid() bool { - return strings.TrimSpace(it.Name) != "" && strings.TrimSpace(it.About) != "" +// IssueTemplateType defines issue template type +type IssueTemplateType string + +const ( + IssueTemplateTypeMarkdown IssueTemplateType = "md" + IssueTemplateTypeYaml IssueTemplateType = "yaml" +) + +// Type returns the type of IssueTemplate, can be "md", "yaml" or empty for known +func (it IssueTemplate) Type() IssueTemplateType { + if it.Name == "config.yaml" || it.Name == "config.yml" { + // ignore config.yaml which is a special configuration file + return "" + } + if ext := filepath.Ext(it.FileName); ext == ".md" { + return IssueTemplateTypeMarkdown + } else if ext == ".yaml" || ext == ".yml" { + return "yaml" + } + return IssueTemplateTypeYaml } diff --git a/modules/templates/base.go b/modules/templates/base.go index 9563650e1..d234d531f 100644 --- a/modules/templates/base.go +++ b/modules/templates/base.go @@ -5,15 +5,16 @@ package templates import ( + "fmt" + "io/fs" "os" + "path/filepath" "strings" "time" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - - "github.com/unrolled/render" ) // Vars represents variables to be render in golang templates @@ -47,8 +48,16 @@ func BaseVars() Vars { } } -func getDirAssetNames(dir string) []string { +func getDirTemplateAssetNames(dir string) []string { + return getDirAssetNames(dir, false) +} + +func getDirAssetNames(dir string, mailer bool) []string { var tmpls []string + + if mailer { + dir += filepath.Join(dir, "mail") + } f, err := os.Stat(dir) if err != nil { if os.IsNotExist(err) { @@ -67,8 +76,13 @@ func getDirAssetNames(dir string) []string { log.Warn("Failed to read %s templates dir. %v", dir, err) return tmpls } + + prefix := "templates/" + if mailer { + prefix += "mail/" + } for _, filePath := range files { - if strings.HasPrefix(filePath, "mail/") { + if !mailer && strings.HasPrefix(filePath, "mail/") { continue } @@ -76,20 +90,39 @@ func getDirAssetNames(dir string) []string { continue } - tmpls = append(tmpls, "templates/"+filePath) + tmpls = append(tmpls, prefix+filePath) } return tmpls } -// HTMLRenderer returns a render. -func HTMLRenderer() *render.Render { - return render.New(render.Options{ - Extensions: []string{".tmpl"}, - Directory: "templates", - Funcs: NewFuncMap(), - Asset: GetAsset, - AssetNames: GetAssetNames, - IsDevelopment: !setting.IsProd, - DisableHTTPErrorRendering: true, - }) +func walkAssetDir(root string, skipMail bool, callback func(path, name string, d fs.DirEntry, err error) error) error { + mailRoot := filepath.Join(root, "mail") + if err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { + name := path[len(root):] + if len(name) > 0 && name[0] == '/' { + name = name[1:] + } + if err != nil { + if os.IsNotExist(err) { + return callback(path, name, d, err) + } + return err + } + if skipMail && path == mailRoot && d.IsDir() { + return fs.SkipDir + } + if util.CommonSkip(d.Name()) { + if d.IsDir() { + return fs.SkipDir + } + return nil + } + if strings.HasSuffix(d.Name(), ".tmpl") || d.IsDir() { + return callback(path, name, d, err) + } + return nil + }); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("unable to get files for template assets in %s: %w", root, err) + } + return nil } diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go index de6968c31..4896580f6 100644 --- a/modules/templates/dynamic.go +++ b/modules/templates/dynamic.go @@ -8,15 +8,12 @@ package templates import ( "html/template" + "io/fs" "os" - "path" "path/filepath" - "strings" texttmpl "text/template" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" ) var ( @@ -36,77 +33,42 @@ func GetAsset(name string) ([]byte, error) { return os.ReadFile(filepath.Join(setting.StaticRootPath, name)) } -// GetAssetNames returns assets list -func GetAssetNames() []string { - tmpls := getDirAssetNames(filepath.Join(setting.CustomPath, "templates")) - tmpls2 := getDirAssetNames(filepath.Join(setting.StaticRootPath, "templates")) +// walkTemplateFiles calls a callback for each template asset +func walkTemplateFiles(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.CustomPath, "templates"), true, callback); err != nil && !os.IsNotExist(err) { + return err + } + if err := walkAssetDir(filepath.Join(setting.StaticRootPath, "templates"), true, callback); err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + +// GetTemplateAssetNames returns list of template names +func GetTemplateAssetNames() []string { + tmpls := getDirTemplateAssetNames(filepath.Join(setting.CustomPath, "templates")) + tmpls2 := getDirTemplateAssetNames(filepath.Join(setting.StaticRootPath, "templates")) return append(tmpls, tmpls2...) } -// Mailer provides the templates required for sending notification mails. -func Mailer() (*texttmpl.Template, *template.Template) { - for _, funcs := range NewTextFuncMap() { - subjectTemplates.Funcs(funcs) +func walkMailerTemplates(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.StaticRootPath, "templates", "mail"), false, callback); err != nil && !os.IsNotExist(err) { + return err } - for _, funcs := range NewFuncMap() { - bodyTemplates.Funcs(funcs) + if err := walkAssetDir(filepath.Join(setting.CustomPath, "templates", "mail"), false, callback); err != nil && !os.IsNotExist(err) { + return err } - - staticDir := path.Join(setting.StaticRootPath, "templates", "mail") - - isDir, err := util.IsDir(staticDir) - if err != nil { - log.Warn("Unable to check if templates dir %s is a directory. Error: %v", staticDir, err) - } - if isDir { - files, err := util.StatDir(staticDir) - - if err != nil { - log.Warn("Failed to read %s templates dir. %v", staticDir, err) - } else { - for _, filePath := range files { - if !strings.HasSuffix(filePath, ".tmpl") { - continue - } - - content, err := os.ReadFile(path.Join(staticDir, filePath)) - if err != nil { - log.Warn("Failed to read static %s template. %v", filePath, err) - continue - } - - buildSubjectBodyTemplate(subjectTemplates, bodyTemplates, strings.TrimSuffix(filePath, ".tmpl"), content) - } - } - } - - customDir := path.Join(setting.CustomPath, "templates", "mail") - - isDir, err = util.IsDir(customDir) - if err != nil { - log.Warn("Unable to check if templates dir %s is a directory. Error: %v", customDir, err) - } - if isDir { - files, err := util.StatDir(customDir) - - if err != nil { - log.Warn("Failed to read %s templates dir. %v", customDir, err) - } else { - for _, filePath := range files { - if !strings.HasSuffix(filePath, ".tmpl") { - continue - } - - content, err := os.ReadFile(path.Join(customDir, filePath)) - if err != nil { - log.Warn("Failed to read custom %s template. %v", filePath, err) - continue - } - - buildSubjectBodyTemplate(subjectTemplates, bodyTemplates, strings.TrimSuffix(filePath, ".tmpl"), content) - } - } - } - - return subjectTemplates, bodyTemplates + return nil +} + +// BuiltinAsset will read the provided asset from the embedded assets +// (This always returns os.ErrNotExist) +func BuiltinAsset(name string) ([]byte, error) { + return nil, os.ErrNotExist +} + +// BuiltinAssetNames returns the names of the embedded assets +// (This always returns nil) +func BuiltinAssetNames() []string { + return nil } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 602afec41..48b62403a 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -24,7 +24,7 @@ import ( "time" "unicode" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/avatars" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" @@ -81,6 +81,9 @@ func NewFuncMap() []template.FuncMap { "AppDomain": func() string { return setting.Domain }, + "AssetVersion": func() string { + return setting.AssetVersion + }, "DisableGravatar": func() bool { return setting.DisableGravatar }, @@ -150,7 +153,6 @@ func NewFuncMap() []template.FuncMap { "DiffTypeToStr": DiffTypeToStr, "DiffLineTypeToStr": DiffLineTypeToStr, "ShortSha": base.ShortSha, - "MD5": base.EncodeMD5, "ActionContent2Commits": ActionContent2Commits, "PathEscape": url.PathEscape, "PathEscapeSegments": util.PathEscapeSegments, @@ -453,6 +455,7 @@ func NewFuncMap() []template.FuncMap { } return items }, + "HasPrefix": strings.HasPrefix, }} } @@ -652,7 +655,7 @@ func Avatar(item interface{}, others ...interface{}) template.HTML { } // AvatarByAction renders user avatars from action. args: action, size (int), class (string) -func AvatarByAction(action *models.Action, others ...interface{}) template.HTML { +func AvatarByAction(action *activities_model.Action, others ...interface{}) template.HTML { action.LoadActUser() return Avatar(action.ActUser, others...) } @@ -851,7 +854,7 @@ func IsMultilineCommitMessage(msg string) bool { // Actioner describes an action type Actioner interface { - GetOpType() models.ActionType + GetOpType() activities_model.ActionType GetActUserName() string GetRepoUserName() string GetRepoName() string @@ -864,33 +867,33 @@ type Actioner interface { } // ActionIcon accepts an action operation type and returns an icon class name. -func ActionIcon(opType models.ActionType) string { +func ActionIcon(opType activities_model.ActionType) string { switch opType { - case models.ActionCreateRepo, models.ActionTransferRepo, models.ActionRenameRepo: + case activities_model.ActionCreateRepo, activities_model.ActionTransferRepo, activities_model.ActionRenameRepo: return "repo" - case models.ActionCommitRepo, models.ActionPushTag, models.ActionDeleteTag, models.ActionDeleteBranch: + case activities_model.ActionCommitRepo, activities_model.ActionPushTag, activities_model.ActionDeleteTag, activities_model.ActionDeleteBranch: return "git-commit" - case models.ActionCreateIssue: + case activities_model.ActionCreateIssue: return "issue-opened" - case models.ActionCreatePullRequest: + case activities_model.ActionCreatePullRequest: return "git-pull-request" - case models.ActionCommentIssue, models.ActionCommentPull: + case activities_model.ActionCommentIssue, activities_model.ActionCommentPull: return "comment-discussion" - case models.ActionMergePullRequest: + case activities_model.ActionMergePullRequest: return "git-merge" - case models.ActionCloseIssue, models.ActionClosePullRequest: + case activities_model.ActionCloseIssue, activities_model.ActionClosePullRequest: return "issue-closed" - case models.ActionReopenIssue, models.ActionReopenPullRequest: + case activities_model.ActionReopenIssue, activities_model.ActionReopenPullRequest: return "issue-reopened" - case models.ActionMirrorSyncPush, models.ActionMirrorSyncCreate, models.ActionMirrorSyncDelete: + case activities_model.ActionMirrorSyncPush, activities_model.ActionMirrorSyncCreate, activities_model.ActionMirrorSyncDelete: return "mirror" - case models.ActionApprovePullRequest: + case activities_model.ActionApprovePullRequest: return "check" - case models.ActionRejectPullRequest: + case activities_model.ActionRejectPullRequest: return "diff" - case models.ActionPublishRelease: + case activities_model.ActionPublishRelease: return "tag" - case models.ActionPullReviewDismissed: + case activities_model.ActionPullReviewDismissed: return "x" default: return "question" diff --git a/modules/templates/htmlrenderer.go b/modules/templates/htmlrenderer.go new file mode 100644 index 000000000..210bb5e73 --- /dev/null +++ b/modules/templates/htmlrenderer.go @@ -0,0 +1,52 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package templates + +import ( + "context" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/watcher" + + "github.com/unrolled/render" +) + +var rendererKey interface{} = "templatesHtmlRendereer" + +// HTMLRenderer returns the current html renderer for the context or creates and stores one within the context for future use +func HTMLRenderer(ctx context.Context) (context.Context, *render.Render) { + rendererInterface := ctx.Value(rendererKey) + if rendererInterface != nil { + renderer, ok := rendererInterface.(*render.Render) + if ok { + return ctx, renderer + } + } + + rendererType := "static" + if !setting.IsProd { + rendererType = "auto-reloading" + } + log.Log(1, log.DEBUG, "Creating "+rendererType+" HTML Renderer") + + renderer := render.New(render.Options{ + Extensions: []string{".tmpl"}, + Directory: "templates", + Funcs: NewFuncMap(), + Asset: GetAsset, + AssetNames: GetTemplateAssetNames, + UseMutexLock: !setting.IsProd, + IsDevelopment: false, + DisableHTTPErrorRendering: true, + }) + if !setting.IsProd { + watcher.CreateWatcher(ctx, "HTML Templates", &watcher.CreateWatcherOpts{ + PathsCallback: walkTemplateFiles, + BetweenCallback: renderer.CompileTemplates, + }) + } + return context.WithValue(ctx, rendererKey, renderer), renderer +} diff --git a/modules/templates/mailer.go b/modules/templates/mailer.go new file mode 100644 index 000000000..0cac1280f --- /dev/null +++ b/modules/templates/mailer.go @@ -0,0 +1,92 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package templates + +import ( + "context" + "html/template" + "io/fs" + "os" + "strings" + texttmpl "text/template" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/watcher" +) + +// Mailer provides the templates required for sending notification mails. +func Mailer(ctx context.Context) (*texttmpl.Template, *template.Template) { + for _, funcs := range NewTextFuncMap() { + subjectTemplates.Funcs(funcs) + } + for _, funcs := range NewFuncMap() { + bodyTemplates.Funcs(funcs) + } + + refreshTemplates := func() { + for _, assetPath := range BuiltinAssetNames() { + if !strings.HasPrefix(assetPath, "mail/") { + continue + } + + if !strings.HasSuffix(assetPath, ".tmpl") { + continue + } + + content, err := BuiltinAsset(assetPath) + if err != nil { + log.Warn("Failed to read embedded %s template. %v", assetPath, err) + continue + } + + assetName := strings.TrimPrefix(strings.TrimSuffix(assetPath, ".tmpl"), "mail/") + + log.Trace("Adding built-in mailer template for %s", assetName) + buildSubjectBodyTemplate(subjectTemplates, + bodyTemplates, + assetName, + content) + } + + if err := walkMailerTemplates(func(path, name string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + return nil + } + + content, err := os.ReadFile(path) + if err != nil { + log.Warn("Failed to read custom %s template. %v", path, err) + return nil + } + + assetName := strings.TrimSuffix(name, ".tmpl") + log.Trace("Adding mailer template for %s from %q", assetName, path) + buildSubjectBodyTemplate(subjectTemplates, + bodyTemplates, + assetName, + content) + return nil + }); err != nil && !os.IsNotExist(err) { + log.Warn("Error whilst walking mailer templates directories. %v", err) + } + } + + refreshTemplates() + + if !setting.IsProd { + // Now subjectTemplates and bodyTemplates are both synchronized + // thus it is safe to call refresh from a different goroutine + watcher.CreateWatcher(ctx, "Mailer Templates", &watcher.CreateWatcherOpts{ + PathsCallback: walkMailerTemplates, + BetweenCallback: refreshTemplates, + }) + } + + return subjectTemplates, bodyTemplates +} diff --git a/modules/templates/static.go b/modules/templates/static.go index 351e48b4d..3265bd9cf 100644 --- a/modules/templates/static.go +++ b/modules/templates/static.go @@ -9,6 +9,7 @@ package templates import ( "html/template" "io" + "io/fs" "os" "path" "path/filepath" @@ -16,10 +17,8 @@ import ( texttmpl "text/template" "time" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" ) var ( @@ -40,95 +39,42 @@ func GetAsset(name string) ([]byte, error) { } else if err == nil { return bs, nil } - return Asset(strings.TrimPrefix(name, "templates/")) + return BuiltinAsset(strings.TrimPrefix(name, "templates/")) } -// GetAssetNames only for chi -func GetAssetNames() []string { +// GetFiles calls a callback for each template asset +func walkTemplateFiles(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.CustomPath, "templates"), true, callback); err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + +// GetTemplateAssetNames only for chi +func GetTemplateAssetNames() []string { realFS := Assets.(vfsgenฐFS) tmpls := make([]string, 0, len(realFS)) for k := range realFS { + if strings.HasPrefix(k, "/mail/") { + continue + } tmpls = append(tmpls, "templates/"+k[1:]) } customDir := path.Join(setting.CustomPath, "templates") - customTmpls := getDirAssetNames(customDir) + customTmpls := getDirTemplateAssetNames(customDir) return append(tmpls, customTmpls...) } -// Mailer provides the templates required for sending notification mails. -func Mailer() (*texttmpl.Template, *template.Template) { - for _, funcs := range NewTextFuncMap() { - subjectTemplates.Funcs(funcs) +func walkMailerTemplates(callback func(path, name string, d fs.DirEntry, err error) error) error { + if err := walkAssetDir(filepath.Join(setting.CustomPath, "templates", "mail"), false, callback); err != nil && !os.IsNotExist(err) { + return err } - for _, funcs := range NewFuncMap() { - bodyTemplates.Funcs(funcs) - } - - for _, assetPath := range AssetNames() { - if !strings.HasPrefix(assetPath, "mail/") { - continue - } - - if !strings.HasSuffix(assetPath, ".tmpl") { - continue - } - - content, err := Asset(assetPath) - if err != nil { - log.Warn("Failed to read embedded %s template. %v", assetPath, err) - continue - } - - buildSubjectBodyTemplate(subjectTemplates, - bodyTemplates, - strings.TrimPrefix( - strings.TrimSuffix( - assetPath, - ".tmpl", - ), - "mail/", - ), - content) - } - - customDir := path.Join(setting.CustomPath, "templates", "mail") - isDir, err := util.IsDir(customDir) - if err != nil { - log.Warn("Failed to check if custom directory %s is a directory. %v", err) - } - if isDir { - files, err := util.StatDir(customDir) - - if err != nil { - log.Warn("Failed to read %s templates dir. %v", customDir, err) - } else { - for _, filePath := range files { - if !strings.HasSuffix(filePath, ".tmpl") { - continue - } - - content, err := os.ReadFile(path.Join(customDir, filePath)) - if err != nil { - log.Warn("Failed to read custom %s template. %v", filePath, err) - continue - } - - buildSubjectBodyTemplate(subjectTemplates, - bodyTemplates, - strings.TrimSuffix( - filePath, - ".tmpl", - ), - content) - } - } - } - - return subjectTemplates, bodyTemplates + return nil } -func Asset(name string) ([]byte, error) { +// BuiltinAsset reads the provided asset from the builtin embedded assets +func BuiltinAsset(name string) ([]byte, error) { f, err := Assets.Open("/" + name) if err != nil { return nil, err @@ -137,7 +83,8 @@ func Asset(name string) ([]byte, error) { return io.ReadAll(f) } -func AssetNames() []string { +// BuiltinAssetNames returns the names of the built-in embedded assets +func BuiltinAssetNames() []string { realFS := Assets.(vfsgenฐFS) results := make([]string, 0, len(realFS)) for k := range realFS { @@ -146,7 +93,8 @@ func AssetNames() []string { return results } -func AssetIsDir(name string) (bool, error) { +// BuiltinAssetIsDir returns if a provided asset is a directory +func BuiltinAssetIsDir(name string) (bool, error) { if f, err := Assets.Open("/" + name); err != nil { return false, err } else { diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go index dfcf9cb01..9350b5e96 100644 --- a/modules/timeutil/since_test.go +++ b/modules/timeutil/since_test.go @@ -5,6 +5,7 @@ package timeutil import ( + "context" "fmt" "os" "testing" @@ -31,7 +32,7 @@ func TestMain(m *testing.M) { setting.Names = []string{"english"} setting.Langs = []string{"en-US"} // setup - translation.InitLocales() + translation.InitLocales(context.Background()) BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) // run the tests diff --git a/modules/timeutil/timestamp.go b/modules/timeutil/timestamp.go index 88008d1fa..40fcb8603 100644 --- a/modules/timeutil/timestamp.go +++ b/modules/timeutil/timestamp.go @@ -54,6 +54,11 @@ func (ts TimeStamp) AsTime() (tm time.Time) { return ts.AsTimeInLocation(setting.DefaultUILocation) } +// AsLocalTime convert timestamp as time.Time in local location +func (ts TimeStamp) AsLocalTime() time.Time { + return time.Unix(int64(ts), 0) +} + // AsTimeInLocation convert timestamp as time.Time in Local locale func (ts TimeStamp) AsTimeInLocation(loc *time.Location) (tm time.Time) { tm = time.Unix(int64(ts), 0).In(loc) diff --git a/modules/translation/i18n/errors.go b/modules/translation/i18n/errors.go new file mode 100644 index 000000000..b485badd1 --- /dev/null +++ b/modules/translation/i18n/errors.go @@ -0,0 +1,12 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package i18n + +import "errors" + +var ( + ErrLocaleAlreadyExist = errors.New("lang already exists") + ErrUncertainArguments = errors.New("arguments to i18n should not contain uncertain slices") +) diff --git a/modules/translation/i18n/format.go b/modules/translation/i18n/format.go new file mode 100644 index 000000000..3fb9e6d6d --- /dev/null +++ b/modules/translation/i18n/format.go @@ -0,0 +1,42 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package i18n + +import ( + "fmt" + "reflect" +) + +// Format formats provided arguments for a given translated message +func Format(format string, args ...interface{}) (msg string, err error) { + if len(args) == 0 { + return format, nil + } + + fmtArgs := make([]interface{}, 0, len(args)) + for _, arg := range args { + val := reflect.ValueOf(arg) + if val.Kind() == reflect.Slice { + // Previously, we would accept Tr(lang, key, a, [b, c], d, [e, f]) as Sprintf(msg, a, b, c, d, e, f) + // but this is an unstable behavior. + // + // So we restrict the accepted arguments to either: + // + // 1. Tr(lang, key, [slice-items]) as Sprintf(msg, items...) + // 2. Tr(lang, key, args...) as Sprintf(msg, args...) + if len(args) == 1 { + for i := 0; i < val.Len(); i++ { + fmtArgs = append(fmtArgs, val.Index(i).Interface()) + } + } else { + err = ErrUncertainArguments + break + } + } else { + fmtArgs = append(fmtArgs, arg) + } + } + return fmt.Sprintf(format, fmtArgs...), err +} diff --git a/modules/translation/i18n/i18n.go b/modules/translation/i18n/i18n.go index bb906f3c0..23b4e23c7 100644 --- a/modules/translation/i18n/i18n.go +++ b/modules/translation/i18n/i18n.go @@ -5,297 +5,48 @@ package i18n import ( - "errors" - "fmt" - "os" - "reflect" - "sync" - "time" - - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - - "gopkg.in/ini.v1" + "io" ) -var ( - ErrLocaleAlreadyExist = errors.New("lang already exists") +var DefaultLocales = NewLocaleStore() - DefaultLocales = NewLocaleStore(true) -) - -type locale struct { - // This mutex will be set if we have live-reload enabled (e.g. dev mode) - reloadMu *sync.RWMutex - - store *LocaleStore - langName string - - idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap - - sourceFileName string - sourceFileInfo os.FileInfo - lastReloadCheckTime time.Time +type Locale interface { + // Tr translates a given key and arguments for a language + Tr(trKey string, trArgs ...interface{}) string + // Has reports if a locale has a translation for a given key + Has(trKey string) bool } -type LocaleStore struct { - // This mutex will be set if we have live-reload enabled (e.g. dev mode) - reloadMu *sync.RWMutex +// LocaleStore provides the functions common to all locale stores +type LocaleStore interface { + io.Closer - langNames []string - langDescs []string - localeMap map[string]*locale - - // this needs to be locked when live-reloading - trKeyToIdxMap map[string]int - - defaultLang string -} - -func NewLocaleStore(isProd bool) *LocaleStore { - store := &LocaleStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)} - if !isProd { - store.reloadMu = &sync.RWMutex{} - } - return store -} - -// AddLocaleByIni adds locale by ini into the store -// if source is a string, then the file is loaded. In dev mode, this file will be checked for live-reloading -// if source is a []byte, then the content is used -// Note: this is not concurrent safe -func (store *LocaleStore) AddLocaleByIni(langName, langDesc string, source interface{}) error { - if _, ok := store.localeMap[langName]; ok { - return ErrLocaleAlreadyExist - } - - l := &locale{store: store, langName: langName} - if store.reloadMu != nil { - l.reloadMu = &sync.RWMutex{} - l.reloadMu.Lock() // Arguably this is not necessary as AddLocaleByIni isn't concurrent safe - but for consistency we do this - defer l.reloadMu.Unlock() - } - - if fileName, ok := source.(string); ok { - l.sourceFileName = fileName - l.sourceFileInfo, _ = os.Stat(fileName) // live-reload only works for regular files. the error can be ignored - } - - var err error - l.idxToMsgMap, err = store.readIniToIdxToMsgMap(source) - if err != nil { - return err - } - - store.langNames = append(store.langNames, langName) - store.langDescs = append(store.langDescs, langDesc) - - store.localeMap[l.langName] = l - - return nil -} - -// readIniToIdxToMsgMap will read a provided ini and creates an idxToMsgMap -func (store *LocaleStore) readIniToIdxToMsgMap(source interface{}) (map[int]string, error) { - iniFile, err := ini.LoadSources(ini.LoadOptions{ - IgnoreInlineComment: true, - UnescapeValueCommentSymbols: true, - }, source) - if err != nil { - return nil, fmt.Errorf("unable to load ini: %w", err) - } - iniFile.BlockMode = false - - idxToMsgMap := make(map[int]string) - - if store.reloadMu != nil { - store.reloadMu.Lock() - defer store.reloadMu.Unlock() - } - - for _, section := range iniFile.Sections() { - for _, key := range section.Keys() { - - var trKey string - if section.Name() == "" || section.Name() == "DEFAULT" { - trKey = key.Name() - } else { - trKey = section.Name() + "." + key.Name() - } - - // Instead of storing the key strings in multiple different maps we compute a idx which will act as numeric code for key - // This reduces the size of the locale idxToMsgMaps - idx, ok := store.trKeyToIdxMap[trKey] - if !ok { - idx = len(store.trKeyToIdxMap) - store.trKeyToIdxMap[trKey] = idx - } - idxToMsgMap[idx] = key.Value() - } - } - iniFile = nil - return idxToMsgMap, nil -} - -func (store *LocaleStore) idxForTrKey(trKey string) (int, bool) { - if store.reloadMu != nil { - store.reloadMu.RLock() - defer store.reloadMu.RUnlock() - } - idx, ok := store.trKeyToIdxMap[trKey] - return idx, ok -} - -// HasLang reports if a language is available in the store -func (store *LocaleStore) HasLang(langName string) bool { - _, ok := store.localeMap[langName] - return ok -} - -// ListLangNameDesc reports if a language available in the store -func (store *LocaleStore) ListLangNameDesc() (names, desc []string) { - return store.langNames, store.langDescs -} - -// SetDefaultLang sets default language as a fallback -func (store *LocaleStore) SetDefaultLang(lang string) { - store.defaultLang = lang -} - -// Tr translates content to target language. fall back to default language. -func (store *LocaleStore) Tr(lang, trKey string, trArgs ...interface{}) string { - l, ok := store.localeMap[lang] - if !ok { - l, ok = store.localeMap[store.defaultLang] - } - - if ok { - return l.Tr(trKey, trArgs...) - } - return trKey -} - -// reloadIfNeeded will check if the locale needs to be reloaded -// this function will assume that the l.reloadMu has been RLocked if it already exists -func (l *locale) reloadIfNeeded() { - if l.reloadMu == nil { - return - } - - now := time.Now() - if now.Sub(l.lastReloadCheckTime) < time.Second || l.sourceFileInfo == nil || l.sourceFileName == "" { - return - } - - l.reloadMu.RUnlock() - l.reloadMu.Lock() // (NOTE: a pre-emption can occur between these two locks so we need to recheck) - defer l.reloadMu.RLock() - defer l.reloadMu.Unlock() - - if now.Sub(l.lastReloadCheckTime) < time.Second || l.sourceFileInfo == nil || l.sourceFileName == "" { - return - } - - l.lastReloadCheckTime = now - sourceFileInfo, err := os.Stat(l.sourceFileName) - if err != nil || sourceFileInfo.ModTime().Equal(l.sourceFileInfo.ModTime()) { - return - } - - idxToMsgMap, err := l.store.readIniToIdxToMsgMap(l.sourceFileName) - if err == nil { - l.idxToMsgMap = idxToMsgMap - } else { - log.Error("Unable to live-reload the locale file %q, err: %v", l.sourceFileName, err) - } - - // We will set the sourceFileInfo to this file to prevent repeated attempts to re-load this broken file - l.sourceFileInfo = sourceFileInfo -} - -// Tr translates content to locale language. fall back to default language. -func (l *locale) Tr(trKey string, trArgs ...interface{}) string { - if l.reloadMu != nil { - l.reloadMu.RLock() - defer l.reloadMu.RUnlock() - l.reloadIfNeeded() - } - - msg, _ := l.tryTr(trKey, trArgs...) - return msg -} - -func (l *locale) tryTr(trKey string, trArgs ...interface{}) (msg string, found bool) { - trMsg := trKey - - // convert the provided trKey to a common idx from the store - idx, ok := l.store.idxForTrKey(trKey) - - if ok { - if msg, found = l.idxToMsgMap[idx]; found { - trMsg = msg // use the translation that we have found - } else if l.langName != l.store.defaultLang { - // No translation available in our current language... fallback to the default language - - // Attempt to get the default language from the locale store - if def, ok := l.store.localeMap[l.store.defaultLang]; ok { - - if def.reloadMu != nil { - def.reloadMu.RLock() - def.reloadIfNeeded() - } - if msg, found = def.idxToMsgMap[idx]; found { - trMsg = msg // use the translation that we have found - } - if def.reloadMu != nil { - def.reloadMu.RUnlock() - } - } - } - } - - if !found && !setting.IsProd { - log.Error("missing i18n translation key: %q", trKey) - } - - if len(trArgs) == 0 { - return trMsg, found - } - - fmtArgs := make([]interface{}, 0, len(trArgs)) - for _, arg := range trArgs { - val := reflect.ValueOf(arg) - if val.Kind() == reflect.Slice { - // Previously, we would accept Tr(lang, key, a, [b, c], d, [e, f]) as Sprintf(msg, a, b, c, d, e, f) - // but this is an unstable behavior. - // - // So we restrict the accepted arguments to either: - // - // 1. Tr(lang, key, [slice-items]) as Sprintf(msg, items...) - // 2. Tr(lang, key, args...) as Sprintf(msg, args...) - if len(trArgs) == 1 { - for i := 0; i < val.Len(); i++ { - fmtArgs = append(fmtArgs, val.Index(i).Interface()) - } - } else { - log.Error("the args for i18n shouldn't contain uncertain slices, key=%q, args=%v", trKey, trArgs) - break - } - } else { - fmtArgs = append(fmtArgs, arg) - } - } - - return fmt.Sprintf(trMsg, fmtArgs...), found + // Tr translates a given key and arguments for a language + Tr(lang, trKey string, trArgs ...interface{}) string + // Has reports if a locale has a translation for a given key + Has(lang, trKey string) bool + // SetDefaultLang sets the default language to fall back to + SetDefaultLang(lang string) + // ListLangNameDesc provides paired slices of language names to descriptors + ListLangNameDesc() (names, desc []string) + // Locale return the locale for the provided language or the default language if not found + Locale(langName string) (Locale, bool) + // HasLang returns whether a given language is present in the store + HasLang(langName string) bool + // AddLocaleByIni adds a new language to the store + AddLocaleByIni(langName, langDesc string, source interface{}) error } // ResetDefaultLocales resets the current default locales // NOTE: this is not synchronized -func ResetDefaultLocales(isProd bool) { - DefaultLocales = NewLocaleStore(isProd) +func ResetDefaultLocales() { + if DefaultLocales != nil { + _ = DefaultLocales.Close() + } + DefaultLocales = NewLocaleStore() } -// Tr use default locales to translate content to target language. -func Tr(lang, trKey string, trArgs ...interface{}) string { - return DefaultLocales.Tr(lang, trKey, trArgs...) +// GetLocales returns the locale from the default locales +func GetLocale(lang string) (Locale, bool) { + return DefaultLocales.Locale(lang) } diff --git a/modules/translation/i18n/i18n_test.go b/modules/translation/i18n/i18n_test.go index 32f7585b3..7940e59c9 100644 --- a/modules/translation/i18n/i18n_test.go +++ b/modules/translation/i18n/i18n_test.go @@ -27,36 +27,34 @@ fmt = %[2]s %[1]s sub = Changed Sub String `) - for _, isProd := range []bool{true, false} { - ls := NewLocaleStore(isProd) - assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1)) - assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2)) - ls.SetDefaultLang("lang1") + ls := NewLocaleStore() + assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1)) + assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2)) + ls.SetDefaultLang("lang1") - result := ls.Tr("lang1", "fmt", "a", "b") - assert.Equal(t, "a b", result) + result := ls.Tr("lang1", "fmt", "a", "b") + assert.Equal(t, "a b", result) - result = ls.Tr("lang2", "fmt", "a", "b") - assert.Equal(t, "b a", result) + result = ls.Tr("lang2", "fmt", "a", "b") + assert.Equal(t, "b a", result) - result = ls.Tr("lang1", "section.sub") - assert.Equal(t, "Sub String", result) + result = ls.Tr("lang1", "section.sub") + assert.Equal(t, "Sub String", result) - result = ls.Tr("lang2", "section.sub") - assert.Equal(t, "Changed Sub String", result) + result = ls.Tr("lang2", "section.sub") + assert.Equal(t, "Changed Sub String", result) - result = ls.Tr("", ".dot.name") - assert.Equal(t, "Dot Name", result) + result = ls.Tr("", ".dot.name") + assert.Equal(t, "Dot Name", result) - result = ls.Tr("lang2", "section.mixed") - assert.Equal(t, `test value; more text`, result) + result = ls.Tr("lang2", "section.mixed") + assert.Equal(t, `test value; more text`, result) - langs, descs := ls.ListLangNameDesc() - assert.Equal(t, []string{"lang1", "lang2"}, langs) - assert.Equal(t, []string{"Lang1", "Lang2"}, descs) + langs, descs := ls.ListLangNameDesc() + assert.Equal(t, []string{"lang1", "lang2"}, langs) + assert.Equal(t, []string{"Lang1", "Lang2"}, descs) - result, found := ls.localeMap["lang1"].tryTr("no-such") - assert.Equal(t, "no-such", result) - assert.False(t, found) - } + found := ls.Has("lang1", "no-such") + assert.False(t, found) + assert.NoError(t, ls.Close()) } diff --git a/modules/translation/i18n/localestore.go b/modules/translation/i18n/localestore.go new file mode 100644 index 000000000..e3b88ad96 --- /dev/null +++ b/modules/translation/i18n/localestore.go @@ -0,0 +1,161 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package i18n + +import ( + "fmt" + + "code.gitea.io/gitea/modules/log" + + "gopkg.in/ini.v1" +) + +// This file implements the static LocaleStore that will not watch for changes + +type locale struct { + store *localeStore + langName string + idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap +} + +type localeStore struct { + // After initializing has finished, these fields are read-only. + langNames []string + langDescs []string + + localeMap map[string]*locale + trKeyToIdxMap map[string]int + + defaultLang string +} + +// NewLocaleStore creates a static locale store +func NewLocaleStore() LocaleStore { + return &localeStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)} +} + +// AddLocaleByIni adds locale by ini into the store +// if source is a string, then the file is loaded +// if source is a []byte, then the content is used +func (store *localeStore) AddLocaleByIni(langName, langDesc string, source interface{}) error { + if _, ok := store.localeMap[langName]; ok { + return ErrLocaleAlreadyExist + } + + store.langNames = append(store.langNames, langName) + store.langDescs = append(store.langDescs, langDesc) + + l := &locale{store: store, langName: langName, idxToMsgMap: make(map[int]string)} + store.localeMap[l.langName] = l + + iniFile, err := ini.LoadSources(ini.LoadOptions{ + IgnoreInlineComment: true, + UnescapeValueCommentSymbols: true, + }, source) + if err != nil { + return fmt.Errorf("unable to load ini: %w", err) + } + iniFile.BlockMode = false + + for _, section := range iniFile.Sections() { + for _, key := range section.Keys() { + var trKey string + if section.Name() == "" || section.Name() == "DEFAULT" { + trKey = key.Name() + } else { + trKey = section.Name() + "." + key.Name() + } + idx, ok := store.trKeyToIdxMap[trKey] + if !ok { + idx = len(store.trKeyToIdxMap) + store.trKeyToIdxMap[trKey] = idx + } + l.idxToMsgMap[idx] = key.Value() + } + } + iniFile = nil + + return nil +} + +func (store *localeStore) HasLang(langName string) bool { + _, ok := store.localeMap[langName] + return ok +} + +func (store *localeStore) ListLangNameDesc() (names, desc []string) { + return store.langNames, store.langDescs +} + +// SetDefaultLang sets default language as a fallback +func (store *localeStore) SetDefaultLang(lang string) { + store.defaultLang = lang +} + +// Tr translates content to target language. fall back to default language. +func (store *localeStore) Tr(lang, trKey string, trArgs ...interface{}) string { + l, _ := store.Locale(lang) + + return l.Tr(trKey, trArgs...) +} + +// Has returns whether the given language has a translation for the provided key +func (store *localeStore) Has(lang, trKey string) bool { + l, _ := store.Locale(lang) + + return l.Has(trKey) +} + +// Locale returns the locale for the lang or the default language +func (store *localeStore) Locale(lang string) (Locale, bool) { + l, found := store.localeMap[lang] + if !found { + var ok bool + l, ok = store.localeMap[store.defaultLang] + if !ok { + // no default - return an empty locale + l = &locale{store: store, idxToMsgMap: make(map[int]string)} + } + } + return l, found +} + +// Close implements io.Closer +func (store *localeStore) Close() error { + return nil +} + +// Tr translates content to locale language. fall back to default language. +func (l *locale) Tr(trKey string, trArgs ...interface{}) string { + format := trKey + + idx, ok := l.store.trKeyToIdxMap[trKey] + if ok { + if msg, ok := l.idxToMsgMap[idx]; ok { + format = msg // use the found translation + } else if def, ok := l.store.localeMap[l.store.defaultLang]; ok { + // try to use default locale's translation + if msg, ok := def.idxToMsgMap[idx]; ok { + format = msg + } + } + } + + msg, err := Format(format, trArgs...) + if err != nil { + log.Error("Error whilst formatting %q in %s: %v", trKey, l.langName, err) + } + return msg +} + +// Has returns whether a key is present in this locale or not +func (l *locale) Has(trKey string) bool { + idx, ok := l.store.trKeyToIdxMap[trKey] + if !ok { + return false + } + _, ok = l.idxToMsgMap[idx] + return ok +} diff --git a/modules/translation/translation.go b/modules/translation/translation.go index fcc101d96..e40a9357f 100644 --- a/modules/translation/translation.go +++ b/modules/translation/translation.go @@ -5,15 +5,16 @@ package translation import ( - "path" + "context" "sort" "strings" + "sync" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/translation/i18n" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/watcher" "golang.org/x/text/language" ) @@ -31,6 +32,7 @@ type LangType struct { } var ( + lock *sync.RWMutex matcher language.Matcher allLangs []*LangType allLangMap map[string]*LangType @@ -43,57 +45,52 @@ func AllLangs() []*LangType { } // InitLocales loads the locales -func InitLocales() { - i18n.ResetDefaultLocales(setting.IsProd) - localeNames, err := options.Dir("locale") - if err != nil { - log.Fatal("Failed to list locale files: %v", err) +func InitLocales(ctx context.Context) { + if lock != nil { + lock.Lock() + defer lock.Unlock() + } else if !setting.IsProd && lock == nil { + lock = &sync.RWMutex{} } - localFiles := make(map[string]interface{}, len(localeNames)) - for _, name := range localeNames { - if options.IsDynamic() { - // Try to check if CustomPath has the file, otherwise fallback to StaticRootPath - value := path.Join(setting.CustomPath, "options/locale", name) + refreshLocales := func() { + i18n.ResetDefaultLocales() + localeNames, err := options.Dir("locale") + if err != nil { + log.Fatal("Failed to list locale files: %v", err) + } - isFile, err := util.IsFile(value) - if err != nil { - log.Fatal("Failed to load %s locale file. %v", name, err) - } - - if isFile { - localFiles[name] = value - } else { - localFiles[name] = path.Join(setting.StaticRootPath, "options/locale", name) - } - } else { + localFiles := make(map[string]interface{}, len(localeNames)) + for _, name := range localeNames { localFiles[name], err = options.Locale(name) if err != nil { log.Fatal("Failed to load %s locale file. %v", name, err) } } - } - supportedTags = make([]language.Tag, len(setting.Langs)) - for i, lang := range setting.Langs { - supportedTags[i] = language.Raw.Make(lang) - } + supportedTags = make([]language.Tag, len(setting.Langs)) + for i, lang := range setting.Langs { + supportedTags[i] = language.Raw.Make(lang) + } - matcher = language.NewMatcher(supportedTags) - for i := range setting.Names { - key := "locale_" + setting.Langs[i] + ".ini" + matcher = language.NewMatcher(supportedTags) + for i := range setting.Names { + key := "locale_" + setting.Langs[i] + ".ini" - if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { - log.Error("Failed to set messages to %s: %v", setting.Langs[i], err) + if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { + log.Error("Failed to set messages to %s: %v", setting.Langs[i], err) + } + } + if len(setting.Langs) != 0 { + defaultLangName := setting.Langs[0] + if defaultLangName != "en-US" { + log.Info("Use the first locale (%s) in LANGS setting option as default", defaultLangName) + } + i18n.DefaultLocales.SetDefaultLang(defaultLangName) } } - if len(setting.Langs) != 0 { - defaultLangName := setting.Langs[0] - if defaultLangName != "en-US" { - log.Info("Use the first locale (%s) in LANGS setting option as default", defaultLangName) - } - i18n.DefaultLocales.SetDefaultLang(defaultLangName) - } + + refreshLocales() langs, descs := i18n.DefaultLocales.ListLangNameDesc() allLangs = make([]*LangType, 0, len(langs)) @@ -108,6 +105,17 @@ func InitLocales() { sort.Slice(allLangs, func(i, j int) bool { return strings.ToLower(allLangs[i].Name) < strings.ToLower(allLangs[j].Name) }) + + if !setting.IsProd { + watcher.CreateWatcher(ctx, "Locales", &watcher.CreateWatcherOpts{ + PathsCallback: options.WalkLocales, + BetweenCallback: func() { + lock.Lock() + defer lock.Unlock() + refreshLocales() + }, + }) + } } // Match matches accept languages @@ -118,16 +126,24 @@ func Match(tags ...language.Tag) language.Tag { // locale represents the information of localization. type locale struct { + i18n.Locale Lang, LangName string // these fields are used directly in templates: .i18n.Lang } // NewLocale return a locale func NewLocale(lang string) Locale { + if lock != nil { + lock.RLock() + defer lock.RUnlock() + } + langName := "unknown" if l, ok := allLangMap[lang]; ok { langName = l.Name } + i18nLocale, _ := i18n.GetLocale(lang) return &locale{ + Locale: i18nLocale, Lang: lang, LangName: langName, } @@ -137,11 +153,6 @@ func (l *locale) Language() string { return l.Lang } -// Tr translates content to target language. -func (l *locale) Tr(format string, args ...interface{}) string { - return i18n.Tr(l.Lang, format, args...) -} - // Language specific rules for translating plural texts var trNLangRules = map[string]func(int64) int{ // the default rule is "en-US" if a language isn't listed here diff --git a/modules/util/path.go b/modules/util/path.go index 0ccc7a1dc..3d4ddec21 100644 --- a/modules/util/path.go +++ b/modules/util/path.go @@ -12,7 +12,6 @@ import ( "path/filepath" "regexp" "runtime" - "strings" ) // EnsureAbsolutePath ensure that a path is absolute, making it @@ -91,7 +90,7 @@ func statDir(dirPath, recPath string, includeDir, isDirOnly, followSymlinks bool statList := make([]string, 0) for _, fi := range fis { - if strings.Contains(fi.Name(), ".DS_Store") { + if CommonSkip(fi.Name()) { continue } @@ -199,3 +198,21 @@ func HomeDir() (home string, err error) { return home, nil } + +// CommonSkip will check a provided name to see if it represents file or directory that should not be watched +func CommonSkip(name string) bool { + if name == "" { + return true + } + + switch name[0] { + case '.': + return true + case 't', 'T': + return name[1:] == "humbs.db" + case 'd', 'D': + return name[1:] == "esktop.ini" + } + + return false +} diff --git a/modules/util/string.go b/modules/util/string.go index 4301f75f9..2da2bc5dc 100644 --- a/modules/util/string.go +++ b/modules/util/string.go @@ -17,13 +17,13 @@ func isSnakeCaseLowerOrNumber(c byte) bool { // ToSnakeCase convert the input string to snake_case format. // // Some samples. -// "FirstName" => "first_name" -// "HTTPServer" => "http_server" -// "NoHTTPS" => "no_https" -// "GO_PATH" => "go_path" -// "GO PATH" => "go_path" // space is converted to underscore. -// "GO-PATH" => "go_path" // hyphen is converted to underscore. // +// "FirstName" => "first_name" +// "HTTPServer" => "http_server" +// "NoHTTPS" => "no_https" +// "GO_PATH" => "go_path" +// "GO PATH" => "go_path" // space is converted to underscore. +// "GO-PATH" => "go_path" // hyphen is converted to underscore. func ToSnakeCase(input string) string { if len(input) == 0 { return "" diff --git a/modules/validation/binding.go b/modules/validation/binding.go index 7baa36ccc..f08f63242 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -9,6 +9,8 @@ import ( "regexp" "strings" + "code.gitea.io/gitea/modules/git" + "gitea.com/go-chi/binding" "github.com/gobwas/glob" ) @@ -24,30 +26,6 @@ const ( ErrRegexPattern = "RegexPattern" ) -// GitRefNamePatternInvalid is regular expression with unallowed characters in git reference name -// They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere. -// They cannot have question-mark ?, asterisk *, or open bracket [ anywhere -var GitRefNamePatternInvalid = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`) - -// CheckGitRefAdditionalRulesValid check name is valid on additional rules -func CheckGitRefAdditionalRulesValid(name string) bool { - // Additional rules as described at https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html - if strings.HasPrefix(name, "/") || strings.HasSuffix(name, "/") || - strings.HasSuffix(name, ".") || strings.Contains(name, "..") || - strings.Contains(name, "//") || strings.Contains(name, "@{") || - name == "@" { - return false - } - parts := strings.Split(name, "/") - for _, part := range parts { - if strings.HasSuffix(part, ".lock") || strings.HasPrefix(part, ".") { - return false - } - } - - return true -} - // AddBindingRules adds additional binding rules func AddBindingRules() { addGitRefNameBindingRule() @@ -67,16 +45,10 @@ func addGitRefNameBindingRule() { IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) - if GitRefNamePatternInvalid.MatchString(str) { + if !git.IsValidRefPattern(str) { errs.Add([]string{name}, ErrGitRefName, "GitRefName") return false, errs } - - if !CheckGitRefAdditionalRulesValid(str) { - errs.Add([]string{name}, ErrGitRefName, "GitRefName") - return false, errs - } - return true, errs }, }) diff --git a/modules/watcher/watcher.go b/modules/watcher/watcher.go new file mode 100644 index 000000000..d737f6ccb --- /dev/null +++ b/modules/watcher/watcher.go @@ -0,0 +1,115 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package watcher + +import ( + "context" + "io/fs" + "os" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/process" + + "github.com/fsnotify/fsnotify" +) + +// CreateWatcherOpts are options to configure the watcher +type CreateWatcherOpts struct { + // PathsCallback is used to set the required paths to watch + PathsCallback func(func(path, name string, d fs.DirEntry, err error) error) error + + // BeforeCallback is called before any files are watched + BeforeCallback func() + + // Between Callback is called between after a watched event has occurred + BetweenCallback func() + + // AfterCallback is called as this watcher ends + AfterCallback func() +} + +// CreateWatcher creates a watcher labelled with the provided description and running with the provided options. +// The created watcher will create a subcontext from the provided ctx and register it with the process manager. +func CreateWatcher(ctx context.Context, desc string, opts *CreateWatcherOpts) { + go run(ctx, desc, opts) +} + +func run(ctx context.Context, desc string, opts *CreateWatcherOpts) { + if opts.BeforeCallback != nil { + opts.BeforeCallback() + } + if opts.AfterCallback != nil { + defer opts.AfterCallback() + } + ctx, _, finished := process.GetManager().AddTypedContext(ctx, "Watcher: "+desc, process.SystemProcessType, true) + defer finished() + + log.Trace("Watcher loop starting for %s", desc) + defer log.Trace("Watcher loop ended for %s", desc) + + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Error("Unable to create watcher for %s: %v", desc, err) + return + } + if err := opts.PathsCallback(func(path, _ string, d fs.DirEntry, err error) error { + if err != nil && !os.IsNotExist(err) { + return err + } + log.Trace("Watcher: %s watching %q", desc, path) + _ = watcher.Add(path) + return nil + }); err != nil { + log.Error("Unable to create watcher for %s: %v", desc, err) + _ = watcher.Close() + return + } + + // Note we don't call the BetweenCallback here + + for { + select { + case event, ok := <-watcher.Events: + if !ok { + _ = watcher.Close() + return + } + log.Debug("Watched file for %s had event: %v", desc, event) + case err, ok := <-watcher.Errors: + if !ok { + _ = watcher.Close() + return + } + log.Error("Error whilst watching files for %s: %v", desc, err) + case <-ctx.Done(): + _ = watcher.Close() + return + } + + // Recreate the watcher - only call the BetweenCallback after the new watcher is set-up + _ = watcher.Close() + watcher, err = fsnotify.NewWatcher() + if err != nil { + log.Error("Unable to create watcher for %s: %v", desc, err) + return + } + if err := opts.PathsCallback(func(path, _ string, _ fs.DirEntry, err error) error { + if err != nil { + return err + } + _ = watcher.Add(path) + return nil + }); err != nil { + log.Error("Unable to create watcher for %s: %v", desc, err) + _ = watcher.Close() + return + } + + // Inform our BetweenCallback that there has been an event + if opts.BetweenCallback != nil { + opts.BetweenCallback() + } + } +} diff --git a/options/license/AGPL-1.0 b/options/license/AGPL-1.0 deleted file mode 100644 index 3c7a40e17..000000000 --- a/options/license/AGPL-1.0 +++ /dev/null @@ -1,48 +0,0 @@ -AFFERO GENERAL PUBLIC LICENSE -Version 1, March 2002 Copyright ยฉ 2002 Affero Inc. -510 Third Street - Suite 225, San Francisco, CA 94107, USA -This license is a modified version of the GNU General Public License copyright (C) 1989, 1991 Free Software Foundation, Inc. made with their permission. Section 2(d) has been added to cover use of software over a computer network. -Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -Preamble -The licenses for most software are designed to take away your freedom to share and change it. By contrast, the Affero General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This Public License applies to most of Affero's software and to any other program whose authors commit to using it. (Some other Affero software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. -When we speak of free software, we are referring to freedom, not price. This General Public License is designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. -To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. -For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. -We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. -Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. -Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. -The precise terms and conditions for copying, distribution and modification follow. -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this Affero General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". - Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. - 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. - You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. - b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. - c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - d) If the Program as you received it is intended to interact with users through a computer network and if, in the version you received, any user interacting with the Program was given the opportunity to request transmission to that user of the Program's complete source code, you must not remove that facility from your modified version of the Program or work based on the Program, and must offer an equivalent opportunity for all users interacting with your Program through a computer network to request immediate transmission by HTTP of the complete source code of your modified version or other derivative work. - These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. - Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. - In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. - 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) - The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. - If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. - 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. - 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. - 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. - If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. - It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. - This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. - 9. Affero Inc. may publish revised and/or new versions of the Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by Affero, Inc. If the Program does not specify a version number of this License, you may choose any version ever published by Affero, Inc. - You may also choose to redistribute modified versions of this program under any version of the Free Software Foundation's GNU General Public License version 3 or higher, so long as that version of the GNU GPL includes terms and conditions substantially equivalent to those of this license. - 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by Affero, Inc., write to us; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/options/license/BSD-2-Clause-FreeBSD b/options/license/BSD-2-Clause-FreeBSD deleted file mode 100644 index 004ec9457..000000000 --- a/options/license/BSD-2-Clause-FreeBSD +++ /dev/null @@ -1,27 +0,0 @@ -The FreeBSD Copyright Copyright 1992-2012 The FreeBSD Project. All rights -reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are -those of the authors and should not be interpreted as representing official -policies, either expressed or implied, of the FreeBSD Project. diff --git a/options/license/BSD-2-Clause-NetBSD b/options/license/BSD-2-Clause-NetBSD deleted file mode 100644 index a84256686..000000000 --- a/options/license/BSD-2-Clause-NetBSD +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2008 The NetBSD Foundation, Inc. All rights reserved. - -This code is derived from software contributed to The NetBSD Foundation by - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/options/license/Fair b/options/license/Fair index 32b6d6aff..430fdb05f 100644 --- a/options/license/Fair +++ b/options/license/Fair @@ -5,5 +5,3 @@ Fair License Usage of the works is permitted provided that this instrument is retained with the works, so that any entity that uses the works is notified of this instrument. DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. - -[2004, Fair License: rhid.com/fair (this URL no longer works)] diff --git a/options/license/MIT-CMU b/options/license/MIT-CMU index 2b11a7b08..0ca287d98 100644 --- a/options/license/MIT-CMU +++ b/options/license/MIT-CMU @@ -2,6 +2,6 @@ By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions: -Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the copyright holder not be used in advertising or publicity pertaining to distribution of the software without specific, written permission. +Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the copyright holder not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE COPYRIGHT HOLDER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/options/license/Python-2.0.1 b/options/license/Python-2.0.1 index 2b90e0400..22f32578d 100644 --- a/options/license/Python-2.0.1 +++ b/options/license/Python-2.0.1 @@ -191,17 +191,3 @@ FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION ----------------------------------------------------------------------- - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/options/license/Spencer-86 b/options/license/Spencer-86 index 8577e881c..ace415744 100644 --- a/options/license/Spencer-86 +++ b/options/license/Spencer-86 @@ -7,5 +7,3 @@ Permission is granted to anyone to use this software for any purpose on any comp 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. - -Beware that some of this code is subtly aware of the way operator precedence is structured in regular expressions. Serious changes in regular-expression syntax might require a total rethink. diff --git a/options/license/Verbatim-man-pages b/options/license/Verbatim-man-pages deleted file mode 100644 index 8a10d8e68..000000000 --- a/options/license/Verbatim-man-pages +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 0000, Obelix the Gaul . - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of -a permission notice identical to this one. - -Since the Linux kernel and libraries are constantly changing, this -manual page may be incorrect or out-of-date. The author(s) assume -no responsibility for errors or omissions, or for damages resulting -from the use of the information contained herein. The author(s) may -not have taken the same level of care in the production of this -manual, which is licensed free of charge, as they might when working -professionally. - -Formatted or processed versions of this manual, if unaccompanied by -the source, must acknowledge the copyright and authors of this work. diff --git a/options/license/gnu-javamail-exception b/options/license/gnu-javamail-exception index 6b24ec821..8f3b9ab0d 100644 --- a/options/license/gnu-javamail-exception +++ b/options/license/gnu-javamail-exception @@ -1 +1 @@ -As a special exception, if you link this library with other files to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License." +As a special exception, if you link this library with other files to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. diff --git a/options/locale/locale_bg-BG.ini b/options/locale/locale_bg-BG.ini index 497aab66c..3a63f3cb8 100644 --- a/options/locale/locale_bg-BG.ini +++ b/options/locale/locale_bg-BG.ini @@ -199,6 +199,7 @@ org_no_results=ะะต ะฑัั…ะฐ ะฝะฐะผะตั€ะตะฝะธ ััŠะพั‚ะฒะตั‚ัั‚ะฒะฐั‰ะธ ะพั€ะณ code_search_results=ะ ะตะทัƒะปั‚ะฐั‚ะธ ะพั‚ ั‚ัŠั€ัะตะฝะต ะทะฐ '%s' code_last_indexed_at=ะŸะพัะปะตะดะฝะพ ะธะฝะดะตะบัะธั€ะฐะฝ %s + [auth] create_new_account=ะ ะตะณะธัั‚ั€ะธั€ะฐะฝะต ะฝะฐ ะฐะบะฐัƒะฝั‚ register_helper_msg=ะ’ะตั‡ะต ะธะผะฐั‚ะต ะฟั€ะพั„ะธะป? ะ’ะฟะธัˆะตั‚ะต ัะต ัะตะณะฐ! diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 2b3ddeace..7eab7b549 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -269,6 +269,7 @@ code_no_results=Nebyl nalezen ลพรกdnรฝ zdrojovรฝ kรณd odpovรญdajรญcรญ hledanรฉmu code_search_results=Vรฝsledky hledรกnรญ pro โ€ž%sโ€œ code_last_indexed_at=Naposledy indexovรกno %s + [auth] create_new_account=Registrovat รบฤet register_helper_msg=Jiลพ mรกte รบฤet? Pล™ihlaste se! diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 84630dbc3..ec2e6ba50 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -276,6 +276,7 @@ code_no_results=Es konnte kein passender Code fรผr deinen Suchbegriff gefunden w code_search_results=Suchergebnisse fรผr โ€ž%sโ€œ code_last_indexed_at=Zuletzt indexiert %s + [auth] create_new_account=Konto anlegen register_helper_msg=Hast du bereits ein Konto? Jetzt anmelden! diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index e06a3e539..9cfeae92a 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -276,6 +276,7 @@ code_no_results=ฮ”ฮตฮฝ ฮฒฯฮญฮธฮทฮบฮต ฯ€ฮทฮณฮฑฮฏฮฟฯ‚ ฮบฯŽฮดฮนฮบฮฑฯ‚ ฯ€ฮฟฯ… ฮฝฮฑ code_search_results=ฮ‘ฯ€ฮฟฯ„ฮตฮปฮญฯƒฮผฮฑฯ„ฮฑ ฮฑฮฝฮฑฮถฮฎฯ„ฮทฯƒฮทฯ‚ ฮณฮนฮฑ '%s' code_last_indexed_at=ฮคฮตฮปฮตฯ…ฯ„ฮฑฮฏฮฟ ฮดฮทฮผฮนฮฟฯ…ฯฮณฮฏฮฑ ฮตฯ…ฯฮตฯ„ฮทฯฮฏฮฟฯ… ฯƒฯ„ฮนฯ‚ %s + [auth] create_new_account=ฮ•ฮณฮณฯฮฑฯ†ฮฎ ฮ›ฮฟฮณฮฑฯฮนฮฑฯƒฮผฮฟฯ register_helper_msg=ฮˆฯ‡ฮตฯ„ฮต ฮฎฮดฮท ฮปฮฟฮณฮฑฯฮนฮฑฯƒฮผฯŒ? ฮฃฯ…ฮฝฮดฮตฮธฮตฮฏฯ„ฮต ฯ„ฯŽฯฮฑ! diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0e309279d..6845680cc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -277,6 +277,9 @@ org_no_results = No matching organizations found. code_no_results = No source code matching your search term found. code_search_results = Search results for '%s' code_last_indexed_at = Last indexed %s +relevant_repositories_tooltip = Repositories that are forks or that have no topic, no icon, and no description are hidden. +relevant_repositories = Only relevant repositories are being shown, show unfiltered results. + [auth] create_new_account = Register Account @@ -1228,6 +1231,8 @@ issues.new.add_reviewer_title = Request review issues.choose.get_started = Get Started issues.choose.blank = Default issues.choose.blank_about = Create an issue from default template. +issues.choose.ignore_invalid_templates = Invalid templates have been ignored +issues.choose.invalid_templates = %v invalid template(s) found issues.no_ref = No Branch/Tag Specified issues.create = Create Issue issues.new_label = New Label @@ -1951,6 +1956,8 @@ settings.event_delete = Delete settings.event_delete_desc = Branch or tag deleted. settings.event_fork = Fork settings.event_fork_desc = Repository forked. +settings.event_wiki = Wiki +settings.event_wiki_desc = Wiki page created, renamed, edited or deleted. settings.event_release = Release settings.event_release_desc = Release published, updated or deleted in a repository. settings.event_push = Push @@ -3128,6 +3135,8 @@ rubygems.dependencies.development = Development Dependencies rubygems.required.ruby = Requires Ruby version rubygems.required.rubygems = Requires RubyGem version rubygems.documentation = For more information on the RubyGems registry, see the documentation. +vagrant.install = To add a Vagrant box, run the following command: +vagrant.documentation = For more information on the Vagrant registry, see the documentation. settings.link = Link this package to a repository settings.link.description = If you link a package with a repository, the package is listed in the repository's package list. settings.link.select = Select Repository diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index ea1ce5474..637f88c9b 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -36,9 +36,9 @@ passcode=Cรณdigo de acceso webauthn_insert_key=Introduzca su clave de seguridad webauthn_sign_in=Presione el botรณn en su clave de seguridad. Si su clave de seguridad no tiene ningรบn botรณn, vuelva a insertarla. -webauthn_press_button=Por favor, preione el botรณn en su clave de seguridadโ€ฆ +webauthn_press_button=Por favor, presione el botรณn de su llave de seguridadโ€ฆ webauthn_use_twofa=Utilice un cรณdigo de doble factor desde su telรฉfono mรณvil -webauthn_error=No se pudo leer la clave de seguridad. +webauthn_error=No se pudo leer su llave de seguridad. webauthn_unsupported_browser=Su navegador no soporta actualmente WebAuthn. webauthn_error_unknown=Ha ocurrido un error desconocido. Por favor, intรฉntelo de nuevo. webauthn_error_insecure=WebAuthn sรณlo soporta conexiones seguras. Para probar sobre HTTP, puede utilizar el origen "localhost" o "127.0.0.1" @@ -277,6 +277,9 @@ org_no_results=No se ha encontrado ninguna organizaciรณn coincidente. code_no_results=No se ha encontrado cรณdigo de fuente que coincida con su tรฉrmino de bรบsqueda. code_search_results=Resultados de bรบsqueda para '%s' code_last_indexed_at=Indexado por รบltima vez %s +relevant_repositories_tooltip=Repositorios que son bifurcaciones o que no tienen ningรบn tema, ningรบn icono, y ninguna descripciรณn estรกn ocultos. +relevant_repositories=Solo se muestran repositorios relevantes, mostrar resultados sin filtrar. + [auth] create_new_account=Registrar una cuenta @@ -533,7 +536,7 @@ twofa=Autenticaciรณn de doble factor account_link=Cuentas vinculadas organization=Organizaciones uid=UUID -webauthn=Claves Seguridades +webauthn=Llaves de Seguridad public_profile=Perfil pรบblico biography_placeholder=Cuรฉntenos un poco mรกs sobre usted @@ -764,7 +767,7 @@ twofa_disable_note=Puede deshabilitar la autenticaciรณn de doble factor si lo ne twofa_disable_desc=Deshabilitar la autenticaciรณn de doble factor harรก su cuenta menos segura. ยฟContinuar? regenerate_scratch_token_desc=Si extraviรณ su cรณdigo de respaldo, o ya lo usรณ para iniciar sesiรณn, puede restablecerlo aquรญ. twofa_disabled=La autenticaciรณn de doble factor ha sido deshabilitada. -scan_this_image=Analiza esta imagen con la aplicaciรณn de autenticaciรณn: +scan_this_image=Escanee esta imagen con su aplicaciรณn de autenticaciรณn: or_enter_secret=O introduzca el secreto: %s then_enter_passcode=E introduzca el cรณdigo de acceso mostrado en la aplicaciรณn: passcode_invalid=El cรณdigo de acceso es incorrecto. Vuelva a intentarlo. @@ -775,7 +778,7 @@ webauthn_desc=Las claves de seguridad son dispositivos hardware que contienen cl webauthn_register_key=Aรฑadir clave de seguridad webauthn_nickname=Apodo webauthn_delete_key=Eliminar clave de seguridad -webauthn_delete_key_desc=Si elimina una clave de seguridad no podrรก utilizarla para registrarte con ella. ยฟContinuar? +webauthn_delete_key_desc=Si elimina una llave de seguridad ya no podrรก utilizarla para iniciar sesiรณn con ella. ยฟContinuar? manage_account_links=Administrar cuentas vinculadas manage_account_links_desc=Estas cuentas externas estรกn vinculadas a su cuenta de Gitea. @@ -1235,9 +1238,9 @@ issues.new_label_placeholder=Nombre etiqueta issues.new_label_desc_placeholder=Descripciรณn issues.create_label=Crear etiqueta issues.label_templates.title=Carga un conjunto predefinido de etiquetas -issues.label_templates.info=No hay etiquetas existentes todavรญa. Crea una etiqueta con "Nueva Etiqueta" o use la etiqueta predefinida: +issues.label_templates.info=Todavรญa no existen etiquetas. Cree una etiqueta con "Nueva Etiqueta" o use un conjunto predefinido de etiquetas: issues.label_templates.helper=Seleccionar un conjunto de etiquetas -issues.label_templates.use=Utilice la etiqueta +issues.label_templates.use=Usar este conjunto de etiquetas issues.label_templates.fail_to_load_file=Error al cargar el archivo de plantilla de etiqueta '%s': %v issues.add_label=aรฑadiรณ la etiqueta %s %s issues.add_labels=aรฑadiรณ las etiquetas %s %s @@ -2205,7 +2208,7 @@ releases.desc=Seguir las versiones y descargas del proyecto. release.releases=Lanzamientos release.detail=Detalles de lanzamiento release.tags=Etiquetas -release.new_release=Nueva Release +release.new_release=Nuevo lanzamiento release.draft=Borrador release.prerelease=Pre-lanzamiento release.stable=Estable @@ -2224,7 +2227,7 @@ release.content=Contenido release.prerelease_desc=Marcar como Pre-Lanzamiento release.prerelease_helper=Marcar este lanzamiento como no es adecuada para usar en producciรณn. release.cancel=Cancelar -release.publish=Publicar Release +release.publish=Publicar lanzamiento release.save_draft=Guardar borrador release.edit_release=Actualizar Lanzamiento release.delete_release=Eliminar Lanzamiento @@ -3128,6 +3131,8 @@ rubygems.dependencies.development=Dependencias de desarrollo rubygems.required.ruby=Requiere versiรณn Ruby rubygems.required.rubygems=Requiere la versiรณn de RubyGem rubygems.documentation=Para obtener mรกs informaciรณn sobre el registro de RubyGems, consulte la documentaciรณn. +vagrant.install=Para aรฑadir un paquete Vagrant, ejecuta el siguiente comando: +vagrant.documentation=Para mรกs informaciรณn sobre el registro de paquetes Vagrant, revisa la documentaciรณn. settings.link=Vincular este paquete a un repositorio settings.link.description=Si enlaza un paquete con un repositorio, el paquete se enumera en la lista de paquetes del repositorio. settings.link.select=Seleccionar repositorio diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index d60b6dcee..0536bd42f 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -254,6 +254,7 @@ code_no_results=ฺฉุฏ ู…ู†ุจุนŒ ู…ุทุงุจู‚ ุจุง ุฌุณุชุฌูˆŒ ุดู…ุง Œุงูุช ู† code_search_results=ู†ุชุงŒุฌ ุฌุณุชุฌูˆ ุจุฑุงŒ '%s ' code_last_indexed_at=ุขุฎุฑŒู† ุจู‡ ุฑูˆุฒุฑุณุงู†Œ ุฏุฑ %s + [auth] create_new_account=ู†ุงู…โ€Œู†ูˆŒุณŒ ุญุณุงุจ ฺฉุงุฑุจุฑŒ register_helper_msg=ู‚ุจู„ุง ุซุจุช ู†ุงู… ฺฉุฑุฏŒุฏุŸ ุงุฒ ุงŒู†ุฌุง ูˆุงุฑุฏ ุดูˆŒุฏ! diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 7c0cc3109..ae95ac844 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -34,9 +34,12 @@ twofa_scratch=Kaksivaiheinen kertakรคyttรถinen koodi passcode=Tunnuskoodi webauthn_insert_key=Aseta turva-avaimesi +webauthn_sign_in=Paina turva-avaimesi painiketta. Jos turva-avaimessasi ei ole painiketta, irroita se ja aseta uudelleen. webauthn_press_button=Paina turva-avaimesi painikettaโ€ฆ +webauthn_use_twofa=Kรคytรค kaksivaihesta vahvistusta puhelimestasi webauthn_error=Turva-avainta ei voitu lukea. webauthn_unsupported_browser=Selaimesi ei tรคllรค hetkellรค tue WebAuthnia. +webauthn_error_unknown=Tuntematon virhe. Yritรค uudelleen. webauthn_error_insecure=WebAuthn tukee vain suojattuja yhteyksiรค. Testaukseen HTTP:n yli, voit kรคyttรครค osoitetta "localhost" tai "127.0.0.1" webauthn_error_unable_to_process=Palvelin ei pystynyt toteuttamaan kutsua. webauthn_error_duplicated=Turva-avainta ei ole sallittu tรคssรค pyynnรถssรค. Varmista, ettei avainta ole jo rekisterรถity. @@ -210,6 +213,7 @@ internal_token_failed=Sisรคisen pรครคsymerkin luonti epรคonnistui: %v save_config_failed=Asetusten tallentaminen epรคonnistui: %v install_success=Tervetuloa! Kiitos kun valitsit Gitean. Pidรค hauskaa! default_keep_email_private=Piilota sรคhkรถpostiosoitteet oletuksena +default_keep_email_private_popup=Piilota oletusarvoisesti uusien kรคyttรคjรคtilien sรคhkรถpostiosoitteet. default_enable_timetracking=Ota ajan seuranta oletusarvoisesti kรคyttรถรถn default_enable_timetracking_popup=Ota kรคyttรถรถn uusien repojen aikaseuranta oletusarvoisesti. no_reply_address=Piilotettu sรคhkรถpostin verkkotunnus @@ -258,6 +262,7 @@ code_no_results=Hakuehtoasi vastaavaa lรคhdekoodia ei lรถytynyt. code_search_results=Hakutulokset: '%s ' code_last_indexed_at=Viimeksi indeksoitu %s + [auth] create_new_account=Rekisterรถi tili register_helper_msg=On jo tili? Kirjaudu sisรครคn nyt! @@ -342,6 +347,7 @@ register_success=Rekisterรถinti onnistui issue.x_mentioned_you=@%s mainitsi sinut: issue.action.push_1=@%[1]s tyรถnsi %[3]d commitin kohteeseen %[2]s issue.action.push_n=@%[1]s tyรถnsi %[3]d committia kohteeseen %[2]s +issue.action.reject=@%[1]s pyysi muutoksia tรคssรค vetopyynnรถssรค. release.title=Otsikko: %s release.note=Huomautus: @@ -489,6 +495,7 @@ comment_type_group_project=Projekti saved_successfully=Asetuksesi tallennettiin onnistuneesti. privacy=Yksityisyys keep_activity_private=Piilota toiminta profiilisivulta +keep_activity_private_popup=Tekee toiminnon nรคkyvรคn vain sinulle ja yllรคpitรคjille lookup_avatar_by_mail=Hae profiilikuva sรคhkรถpostin perusteella federated_avatar_lookup=Ulkopuolinen profiilikuvan haku @@ -601,6 +608,8 @@ generate_token=Luo pรครคsymerkki generate_token_success=Uusi pรครคsymerkkisi on nyt luotu. Kopioi se nyt, koska sitรค ei nรคytetรค enรครค uudelleen. delete_token=Poista access_token_deletion=Poista pรครคsymerkki +access_token_deletion_cancel_action=Peruuta +access_token_deletion_confirm_action=Poista edit_oauth2_application=Muokkaa OAuth2 sovellusta remove_oauth2_application=Poista OAuth2 sovellus @@ -647,6 +656,7 @@ visibility.public=Julkinen visibility.public_tooltip=Nรคkyvissรค kaikille kรคyttรคjille visibility.limited=Rajattu visibility.private=Yksityinen +visibility.private_tooltip=Nรคkyy vain organisaation jรคsenille [repo] new_repo_helper=Repo sisรคltรครค kaikki projektitiedostot, mukaan lukien revisiohistorian. Onko sinulla repo jo muualla? Voit siirtรครค repon. @@ -714,7 +724,10 @@ migrate.github_token_desc=Voit laittaa yhden tai useamman pรครคsymerkin pilkulla migrate.permission_denied=Sinun ei sallita tuovan paikallisia repoja. migrate.failed=Siirto epรคonnistui: %v migrate.migrate_items_options=Pรครคsymerkki vaaditaan lisรคkohteiden siirtรคmiseen +migrate.migrating=Tuodaan kohteesta %s ... +migrate.migrating_failed=Tuonti kohteesta %s epรคonnistui. migrate.migrating_failed.error=Virhe: %s +migrate.migrating_git=Tuodaan Git-tietoja mirror_from=peilaus alkaen forked_from=forkattu lรคhteestรค @@ -722,7 +735,7 @@ unwatch=Lopeta tarkkailu watch=Tarkkaile unstar=Poista tรคhti star=Tรคhti -download_archive=Lataa varasto +download_archive=Lataa repo no_desc=Ei kuvausta quick_guide=Pikaopas @@ -790,6 +803,7 @@ editor.upload_files_to_dir=Lataa tiedostot kohteeseen '%s' editor.require_signed_commit=Haara vaatii vahvistetun commitin commits.commits=Commitit +commits.nothing_to_compare=Nรคmรค haarat vastaavat toisiaan. commits.find=Haku commits.search_all=Kaikki haarat commits.author=Tekijรค @@ -826,11 +840,14 @@ projects.open=Avaa projects.close=Sulje issues.desc=Ongelmien, tehtรคvien ja merkkipaalujen hallinta. +issues.filter_assignees=Suodata kรคyttรคjiรค issues.filter_milestones=Suodata merkkipaalu issues.new=Uusi ongelma issues.new.labels=Tunnisteet +issues.new.add_labels_title=Aseta tunniste issues.new.no_label=Ei tunnistetta issues.new.clear_labels=Tyhjennรค tunnisteet +issues.new.no_items=Ei kohteita issues.new.milestone=Merkkipaalu issues.new.add_milestone_title=Aseta merkkipaalu issues.new.no_milestone=Ei merkkipaalua @@ -838,6 +855,7 @@ issues.new.clear_milestone=Tyhjennรค merkkipaalu issues.new.open_milestone=Avoimet merkkipaalut issues.new.closed_milestone=Suljetut merkkipaalut issues.new.assignees=Kรคsittelijรค +issues.new.add_assignees_title=Osoita kรคyttรคjille issues.new.clear_assignees=Tyhjennรค kรคsittelijรค issues.new.no_assignees=Ei kรคsittelijรครค issues.choose.blank=Oletus @@ -849,8 +867,12 @@ issues.new_label_desc_placeholder=Kuvaus issues.create_label=Luo tunniste issues.label_templates.helper=Valitse tunnistejoukko issues.add_milestone_at=`lisรคsi tรคmรคn merkkipaaluun %s %s` +issues.change_milestone_at=`vaihtoi merkkipaalun %s merkkipaaluun %s %s` +issues.remove_milestone_at=`poisti tรคmรคn %s merkkipaalusta %s` +issues.remove_project_at=`poisti tรคmรคn %s projektista %s` issues.deleted_milestone=`(poistettu)` issues.self_assign_at=`itse otti tรคmรคn kรคsittelyyn %s` +issues.change_title_at=`muutti otsikon %s otsikoksi %s %s` issues.delete_branch_at=`poisti haaran %s %s` issues.filter_label=Tunniste issues.filter_label_exclude=`Kรคytรค alt + klikkaus/rivinvaihto poissulkeaksesi tunnisteita` @@ -892,6 +914,7 @@ issues.commented_at=`kommentoi %s` issues.delete_comment_confirm=Haluatko varmasti poistaa tรคmรคn kommentin? issues.context.copy_link=Kopioi linkki issues.context.quote_reply=Vastaa lainaamalla +issues.context.reference_issue=Viittaa uudesa ongelmassa issues.context.edit=Muokkaa issues.context.delete=Poista issues.no_content=Sisรคltรถรค ei vielรค ole. @@ -936,9 +959,11 @@ issues.lock.reason=Lukitsemisen syy issues.lock.title=Lukitse keskustelu tรคstรค ongelmasta. issues.unlock.title=Avaa keskustelu tรคstรค ongelmasta. issues.tracker=Ajan seuranta +issues.start_tracking_short=Aloita ajanotto issues.start_tracking=Aloita ajan seuranta issues.start_tracking_history=`aloitti tyรถskentelyn %s` issues.tracker_auto_close=Ajan seuranta pysรคhtyy automaattisesti kun tรคmรค ongelma on suljettu +issues.stop_tracking=Pysรคytรค ajanotto issues.stop_tracking_history=`lopetti tyรถskentelyn %s` issues.add_time=Lisรครค aika kรคsin issues.add_time_short=Lisรครค aika @@ -949,30 +974,44 @@ issues.add_time_minutes=Minuuttia issues.add_time_sum_to_small=Aikaa ei syรถtetty. issues.time_spent_from_all_authors=`Kรคytetty kokonaisaika: %s` issues.due_date=Mรครคrรคpรคivรค +issues.push_commit_1=lisรคsi %d commitin %s +issues.push_commits_n=lisรคsi %d committia %s issues.due_date_form=vvvv-kk-pp issues.due_date_form_edit=Muokkaa issues.due_date_form_remove=Poista issues.due_date_not_set=Mรครคrรคpรคivรครค ei asetettu. issues.due_date_overdue=Myรถhรคssรค issues.dependency.title=Riippuvuudet +issues.dependency.issue_no_dependencies=Riippuvuuksia ei asetettu. +issues.dependency.pr_no_dependencies=Riippuvuuksia ei asetettu. issues.dependency.add=Lisรครค riippuvuusโ€ฆ issues.dependency.cancel=Peru issues.dependency.remove=Poista issues.dependency.remove_info=Poistรค tรคmรค riippuvuus issues.review.self.approval=Et voi hyvรคksyรค omia vetopyyntรถjรค. +issues.review.self.rejection=Et voi pyytรครค muutoksia omaan vetopyyntรถรถn. issues.review.approve=hyvรคksyi nรคmรค muutokset %s issues.review.left_comment=jรคtti kommentin issues.review.pending=Odottaa +issues.review.pending.tooltip=Tรคmรค kommentti ei tรคllรค hetkellรค nรคy muille kรคyttรคjille. Lรคhettรครคksesi odottavat kommentit, valitse '%s' -> '%s/%s/%s' sivun ylรคreunassa. +issues.review.show_resolved=Nรคytรค ratkaisu +issues.review.hide_resolved=Piilota ratkaisu issues.reference_issue.body=Kuvaus issues.content_history.deleted=poistettu issues.content_history.edited=muokattu issues.content_history.created=luotu -pulls.new=Uusi pull pyyntรถ +pulls.new=Uusi vetopyyntรถ +pulls.compare_changes=Uusi vetopyyntรถ +pulls.has_viewed_file=Katsottu +pulls.viewed_files_label=%[1]d / %[2]d tiedostoa katsottu +pulls.compare_compare=vedรค kohteesta pulls.filter_branch=Suodata branch pulls.no_results=Tuloksia ei lรถytynyt. -pulls.nothing_to_compare=Nรคmรค haarat ovat samanlaisia. Ei ole tarvetta luoda vetopyyntรถรค. +pulls.nothing_to_compare=Nรคmรค haarat vastaavat toisiaan. Ei ole tarvetta luoda vetopyyntรถรค. +pulls.nothing_to_compare_and_allow_empty_pr=Nรคmรค haarat vastaavat toisiaan. Vetopyyntรถ tulee olemaan tyhjรค. +pulls.has_pull_request=`Vetopyyntรถ haarojen vรคlillรค on jo olemassa: %[2]s#%[3]d` pulls.create=Luo Pull-pyyntรถ pulls.title_desc=haluaa yhdistรครค %[1]d committia lรคhteestรค %[2]s kohteeseen %[3]s pulls.merged_title_desc=yhdistetty %[1]d committia lรคhteestรค %[2]s kohteeseen %[3]s %[4]s @@ -981,6 +1020,9 @@ pulls.tab_commits=Commitit pulls.tab_files=Muuttuneet tiedostot pulls.merged=Yhdistetty pulls.has_merged=Vetopyyntรถ on yhdistetty. +pulls.title_wip_desc=`Aloita otsikko sanalla %s estรครคksesi vetopyynnรถn yhdistรคmisen vahingossa.` +pulls.add_prefix=Lisรครค %s etuliite +pulls.remove_prefix=Poista %s etuliite pulls.can_auto_merge_desc=Tรคmรค pull-pyyntรถ voidaan yhdistรครค automaattisesti. @@ -1113,18 +1155,37 @@ settings.githook_edit_desc=Jos koukku ei ole kรคytรถssรค, esitellรครคn esimerkki settings.githook_name=Koukun nimi settings.githook_content=Koukun sisรคltรถ settings.update_githook=Pรคivitys koukku +settings.payload_url=Kohde URL settings.http_method=HTTP-menetelmรค settings.secret=Salaus settings.slack_username=Kรคyttรคjรคtunnus settings.slack_icon_url=Kuvakkeen URL settings.discord_username=Kรคyttรคjรคtunnus +settings.event_desc=Triggerรถi: +settings.event_send_everything=Kaikki tapahtumat +settings.event_choose=Mukautetut tapahtumatโ€ฆ +settings.event_header_repository=Repon tapahtumat settings.event_create=Luo +settings.event_create_desc=Haara tai tagi luotu. settings.event_delete=Poista +settings.event_delete_desc=Haara tai tagi poistettu. settings.event_release_desc=Julkaisu julkaistu, pรคivitetty tai poistettu varastosta. settings.event_push=Tyรถnnรค +settings.event_push_desc=Git push repoon. settings.event_repository=Repo +settings.event_repository_desc=Repo luotu tai poistettu. +settings.event_header_issue=Ongelmien tapahtumat +settings.event_issues_desc=Ongelma avattu, suljettu, avattu uudelleen tai muokattu. +settings.event_issue_assign=Ongelma mรครคritetty +settings.event_issue_assign_desc=Ongelma osoitettu tai osoitus poistettu. +settings.event_issue_label_desc=Ongelman tunnisteet pรคivitetty tai tyhjennetty. +settings.event_issue_milestone_desc=Ongelma merkkipaaluteettu tai merkkipaalu-osoitus poistettu. settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu. +settings.event_header_pull_request=Vetopyyntรถjen tapahtumat settings.event_pull_request=Vetopyyntรถ +settings.event_package_desc=Paketti on luotu tai poistettu repossa. +settings.active_helper=Tiedot kรคynnistetyistรค tapahtumista lรคhetetรครคn tรคhรคn webkoukun URL-osoitteeseen. +settings.add_hook_success=Uusi webkoukku on lisรคtty. settings.update_webhook=Pรคivitรค webkoukku settings.delete_webhook=Poista webkoukku settings.recent_deliveries=Viimeisimmรคt toimitukset @@ -1132,6 +1193,7 @@ settings.hook_type=Koukkutyyppi settings.slack_token=Pรครคsymerkki settings.slack_domain=Verkkotunnus settings.slack_channel=Kanava +settings.add_web_hook_desc=Integroi %s repoon. settings.web_hook_name_gitea=Gitea settings.web_hook_name_gogs=Gogs settings.web_hook_name_slack=Slack @@ -1175,13 +1237,21 @@ settings.no_protected_branch=Suojattuja haaroja ei ole. settings.edit_protected_branch=Muokkaa settings.protected_branch_required_approvals_min=Vaadittavat hyvรคksynnรคt ei voi olla negatiivinen. settings.tags=Tagit +settings.tags.protection=Tagien suojaaminen settings.tags.protection.pattern=Tagin kuvio +settings.tags.protection.allowed=Sallitut +settings.tags.protection.allowed.users=Sallitut kรคyttรคjรคt +settings.tags.protection.allowed.teams=Sallitut tiimit +settings.tags.protection.allowed.noone=Ei kukaan +settings.tags.protection.create=Suojaa tagi +settings.tags.protection.none=Suojattuja tageja ei ole. settings.tags.protection.pattern.description=Voit kรคyttรครค yhtรค nimeรค tai glob-kuviota tai sรครคnnรถllistรค lauseketta, joka tรคsmรครค useisiin tageihin. Lue lisรครค suojatut tagit oppaasta. settings.bot_token=Botti pรครคsymerkki settings.matrix.homeserver_url=Kotipalvelimen URL settings.matrix.access_token=Pรครคsymerkki settings.archive.button=Arkistoi repo settings.archive.header=Arkistoi tรคmรค repo +settings.archive.tagsettings_unavailable=Tagien asetukset eivรคt ole saatavilla, jos repo on arkistoitu. settings.lfs=LFS settings.lfs_filelist=LFS-tiedostot tallennettu tรคhรคn repoon settings.lfs_no_lfs_files=LFS-tiedostoja ei ole tallennettu tรคhรคn repoon. @@ -1224,10 +1294,15 @@ diff.view_file=Nรคytรค tiedosto diff.file_image_width=Leveys diff.file_image_height=Korkeus diff.file_byte_size=Koko +diff.comment.markdown_info=Muotoilu markdownilla tuettu. +diff.comment.add_single_comment=Lisรครค yksittรคinen kommentti diff.comment.add_review_comment=Lisรครค kommentti +diff.comment.start_review=Aloita tarkistus diff.comment.reply=Vastaa +diff.review.header=Lรคhetรค arvio diff.review.comment=Kommentoi diff.review.approve=Hyvรคksy +diff.review.reject=Pyydรค muutoksia release.releases=Julkaisut release.tags=Tagit @@ -1251,6 +1326,9 @@ release.publish=Julkaise versio release.save_draft=Tallenna luonnos release.edit_release=Pรคivitรค julkaisu release.delete_release=Poista julkaisu +release.delete_tag=Poista tagi +release.deletion_tag_desc=Poistetaanko tรคmรค tagi reposta? Repon sisรคltรถ ja historia pysyvรคt muuttumattomina. Jatketaanko? +release.deletion_tag_success=Tagi on poistettu. release.tag_name_invalid=Tagin nimi ei ole kelvollinen. release.downloads=Lataukset @@ -1304,7 +1382,9 @@ settings.visibility.private_shortname=Yksityinen settings.update_settings=Pรคivitรค asetukset settings.delete=Poista organisaatio settings.delete_account=Poista tรคmรค organisaatio +settings.delete_prompt=Organisaatio poistetaan pysyvรคsti, ja tรคtรค EI VOI peruuttaa myรถhemmin! settings.confirm_delete_account=Vahvista poisto +settings.hooks_desc=Lisรครค webkoukkuja, jotka suoritetaan kaikissa repoissa tรคssรค organisaatiossa. members.membership_visibility=Jรคsenyyden nรคkyvyys: @@ -1538,6 +1618,7 @@ config.show_registration_button=Nรคytรค rekisterรถidy painike config.disable_key_size_check=Poista kรคytรถstรค avaimen vรคhimmรคiskoko tarkistus config.enable_captcha=Ota CAPTCHA kรคyttรถรถn config.active_code_lives=Aktiivinen koodi elรคmรคt ennen vanhenemista +config.default_keep_email_private=Piilota sรคhkรถpostiosoitteet oletuksena config.default_visibility_organization=Uuden organisaation oletusnรคkyvyys config.webhook_config=Webkoukku asetukset @@ -1592,6 +1673,7 @@ monitor.queues=Jonot monitor.queue=Jono: %s monitor.queue.name=Nimi monitor.queue.type=Tyyppi +monitor.queue.pool.addworkers.desc=Lisรครค kรคsittelijรถitรค tรคhรคn pooliin aikakatkaisulla tai ilman. Jos asetat aikakatkaisun, nรคmรค kรคsittelijรคt poistetaan poolista kun aikakatkaisu on pรครคttynyt. @@ -1612,7 +1694,9 @@ create_repo=luotu repo %s rename_repo=uudelleennimetty repo %[1]s nimelle %[3]s transfer_repo=siirretty repo %s kohteeseen %s push_tag=tyรถnsi tagin %[3]s kohteeseen %[4]s +delete_tag=poisti tagin %[2]s kohteesta %[3]s compare_commits_general=Vertaa committeja +create_branch=loi haaran %[3]s repossa %[4]s [tool] ago=%s sitten diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 18eb44b16..053c2da21 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -277,6 +277,8 @@ org_no_results=Aucune organisation correspondante n'a รฉtรฉ trouvรฉe. code_no_results=Aucun code source correspondant ร  votre terme de recherche n'a รฉtรฉ trouvรฉ. code_search_results=Rรฉsultats de recherche pour "%s" code_last_indexed_at=Derniรจre indexation %s +relevant_repositories_tooltip=Les dรฉpรดts qui sont des forks ou qui n'ont aucun sujet, aucune icรดne et aucune description sont cachรฉs. + [auth] create_new_account=Crรฉer un compte @@ -376,6 +378,7 @@ issue_assigned.pull=@%[1]s vous a assignรฉ ร  la demande dโ€™ajout %[2]s dans le issue_assigned.issue=@%[1]s vous a assignรฉ le ticket %[2]s dans le dรฉpรดt %[3]s. issue.x_mentioned_you=@%s vous a mentionnรฉ: +issue.action.force_push=%[1]s a forcรฉ la mise ร  jour de %[2]s depuis %[3]s vers %[4]s. issue.action.approve=@%[1]s a approuvรฉ cette demande d'ajout. issue.action.reject=@%[1]s a demandรฉ des modifications sur cette demande d'ajout. issue.action.review=@%[1]s a commentรฉ sur cette demande d'ajout. @@ -435,8 +438,10 @@ size_error=` doit รชtre ร  la taille de %s.` min_size_error=` %s caractรจres minimum ` max_size_error=` %s caractรจres maximum ` email_error=` adresse e-mail invalide ` +url_error=`'%s' n'est pas une URL valide.` include_error=`doit contenir la sous-chaรฎne '%s'.` glob_pattern_error=` le motif de dรฉveloppement est invalide : %s.` +regex_pattern_error=` le motif regex est invalide : %s.` unknown_error=Erreur inconnue : captcha_incorrect=Le code CAPTCHA est incorrect. password_not_match=Les mots de passe ne correspondent pas. @@ -481,6 +486,7 @@ auth_failed=ร‰chec d'authentification : %v still_own_repo=Ce compte possรจde toujours un ou plusieurs dรฉpรดts, vous devez d'abord les supprimer ou les transfรฉrer. still_has_org=Votre compte est un membre dโ€™une ou plusieurs organisations, veuillez d'abord les quitter. org_still_own_repo=Cette organisation possรจde encore un ou plusieurs dรฉpรดts. Vous devez d'abord les supprimer ou les transfรฉrer. +org_still_own_packages=Cette organisation possรจde encore un ou plusieurs paquets. Vous devez d'abord les supprimer. target_branch_not_exist=La branche cible n'existe pas. @@ -521,6 +527,7 @@ twofa=Authentification ร  deux facteurs account_link=Comptes associรฉs organization=Organisations uid=ID d'Utilisateur +webauthn=Clรฉs de sรฉcuritรฉ public_profile=Profil public biography_placeholder=Parlez-nous un peu de vous @@ -631,6 +638,8 @@ ssh_key_been_used=Cette clef SSH a dรฉjร  รฉtรฉ ajoutรฉe au serveur. ssh_key_name_used=Une clรฉ SSH avec le mรชme nom existe dรฉjร  sur votre compte. ssh_principal_been_used=Ce principal a dรฉjร  รฉtรฉ ajoutรฉ au serveur. gpg_key_id_used=Une clef GPG publique avec le mรชme identifiant existe dรฉjร . +gpg_no_key_email_found=Cette clรฉ GPG ne correspond ร  aucune adresse e-mail activรฉe et associรฉe avec votre compte. Elle peut toujours รชtre ajoutรฉe si vous signez le jeton fourni. +gpg_key_matched_identities=Identitรฉs correspondantes : gpg_key_verified=Clรฉ vรฉrifiรฉe gpg_key_verify=Vรฉrifier gpg_invalid_token_signature=La clรฉ GPG fournie, la signature et le jeton ne correspondent pas ou le jeton n'est pas ร  jour. @@ -640,6 +649,9 @@ gpg_token_help=Vous pouvez gรฉnรฉrer une signature en utilisant : gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig gpg_token_signature=Signature GPG renforcรฉe key_signature_gpg_placeholder=Commence par '-----BEGIN PGP SIGNATURE-----' +verify_gpg_key_success=La clef GPG '%s' a รฉtรฉ vรฉrifiรฉe. +ssh_key_verified=Clรฉ vรฉrifiรฉe +ssh_key_verify=Vรฉrifier ssh_token_required=Vous devez fournir une signature pour le jeton ci-dessous ssh_token=Jeton ssh_token_help=Vous pouvez gรฉnรฉrer une signature en utilisant : @@ -746,10 +758,14 @@ passcode_invalid=Le mot de passe est invalide. Rรฉessayez. twofa_enrolled=L'authentification ร  deux facteurs a รฉtรฉ activรฉe pour votre compte. Gardez votre jeton de secours (%s) en lieu sรปr car il ne vous sera montrรฉ qu'une seule fois ! twofa_failed_get_secret=Impossible d'obtenir le secret. +webauthn_register_key=Ajouter une clรฉ de sรฉcuritรฉ +webauthn_nickname=Pseudonyme +webauthn_delete_key=Supprimer la clรฉ de sรฉcuritรฉ manage_account_links=Gรฉrer les comptes liรฉs manage_account_links_desc=Ces comptes externes sont liรฉs ร  votre compte Gitea. account_links_not_available=Il n'y a pour l'instant pas de compte externe connectรฉ ร  votre compte Gitea. +link_account=Lier un Compte remove_account_link=Supprimer un compte liรฉ remove_account_link_desc=Supprimer un compte liรฉ rรฉvoquera son accรจs ร  votre compte Gitea. Continuer ? remove_account_link_success=Le compte liรฉ a รฉtรฉ supprimรฉ. @@ -828,6 +844,7 @@ default_branch_helper=La branche par dรฉfaut est la branche de base pour les dem mirror_prune=Purger mirror_prune_desc=Supprimer les rรฉfรฉrences externes obsolรจtes mirror_interval_invalid=L'intervalle de synchronisation est invalide. +mirror_sync_on_commit=Synchroniser quand les commits sont poussรฉs mirror_address=Cloner depuis une URL mirror_address_desc=Insรฉrez tous les identifiants requis dans la section Autorisation. mirror_address_url_invalid=L'url fournie est invalide. Vous devez รฉchapper tous les composants de l'url correctement. @@ -895,6 +912,7 @@ form.name_pattern_not_allowed="%s" n'est pas autorisรฉ dans un nom de dรฉpรดt. need_auth=Autorisation migrate_options=Options de migration migrate_service=Service de migration +migrate_options_mirror_helper=Ce dรฉpรดt sera un miroir migrate_options_lfs=Migrer les fichiers LFS migrate_options_lfs_endpoint.label=Point d'accรจs LFS migrate_options_lfs_endpoint.description=La migration va tenter d'utiliser votre dรฉpรดt Git distant pour dรฉterminer le serveur LFS. Vous pouvez รฉgalement spรฉcifier un point d'accรจs personnalisรฉ si les donnรฉes LFS du dรฉpรดt sont stockรฉes ailleurs. @@ -923,11 +941,14 @@ migrate.migrate=Migrer depuis %s migrate.migrating=Migration de %s ... migrate.migrating_failed=La migration de %s a รฉchouรฉ. migrate.migrating_failed.error=Erreur: %s +migrate.migrating_failed_no_addr=ร‰chec de la migration. +migrate.github.description=Migrer les donnรฉes depuis github.com ou dโ€™autres instances de GitHub. migrate.git.description=Migrer uniquement un dรฉpรดt depuis nโ€™importe quel service Git. migrate.gitlab.description=Migrer les donnรฉes depuis gitlab.com ou dโ€™autres instances de GitLab. migrate.gitea.description=Migrer les donnรฉes depuis gitea.com ou dโ€™autres instances de Gitea. migrate.gogs.description=Migrer les donnรฉes depuis notabug.org ou dโ€™autres instances de Gogs. migrate.onedev.description=Migrer les donnรฉes depuis code.onedev.io ou dโ€™autre instance de OneDev. +migrate.codebase.description=Migrer les donnรฉes depuis codebasehq.com. migrate.migrating_git=Migration des donnรฉes Git migrate.migrating_topics=Migration des sujets migrate.migrating_milestones=Migration des jalons @@ -969,6 +990,7 @@ tags=Tags issues=Tickets pulls=Demandes d'ajout project_board=Projets +packages=Paquets labels=ร‰tiquettes org_labels_desc=Les รฉtiquettes de niveau d'une organisation peuvent รชtre utilisรฉs avec tous les dรฉpรดts de cette organisation org_labels_desc_manage=gรฉrer @@ -988,10 +1010,14 @@ file_view_rendered=Voir le rendu file_view_raw=Voir le Raw file_permalink=Lien permanent file_too_large=Le fichier est trop gros pour รชtre affichรฉ. +invisible_runes_header=`Ce fichier contient des caractรจres Unicode invisibles !` +ambiguous_runes_header=`Ce fichier contient des caractรจres Unicode ambigus !` invisible_runes_line=`Cette ligne contient des caractรจres Unicode invisibles` ambiguous_runes_line=`Cette ligne contient des caractรจres Unicode ambigus` ambiguous_character=`%[1]c [U+%04[1]X] peut รชtre confondu avec %[2]c [U+%04[2]X]` +escape_control_characters=ร‰chapper +unescape_control_characters=Annuler l'รฉchappement file_copy_permalink=Copier le lien permanent video_not_supported_in_browser=Votre navigateur ne supporte pas le tag HTML5 "video". audio_not_supported_in_browser=Votre navigateur ne supporte pas la balise ยซย audioย ยป HTML5. @@ -1209,6 +1235,8 @@ issues.filter_milestone=Jalon issues.filter_milestone_no_select=Tous les jalons issues.filter_assignee=Assignรฉ issues.filter_assginee_no_select=Toutes les affectations +issues.filter_poster=Auteur +issues.filter_poster_no_select=Tous les auteurs issues.filter_type=Type issues.filter_type.all_issues=Tous les tickets issues.filter_type.assigned_to_you=Qui vous sont assignรฉs @@ -1267,7 +1295,7 @@ issues.ref_reopening_from=`a rรฉfรฉrencรฉ une pull request %[4]s issues.ref_closed_from=`a fermรฉ ce ticket %[4]s %[2]s` issues.ref_reopened_from=`a rรฉouvert ce ticket %[4]s %[2]s` issues.ref_from=`de %[1]s` -issues.poster=Publier +issues.poster=ร‰diteur issues.collaborator=Collaborateur issues.owner=Propriรฉtaire issues.re_request_review=Redemander la revue @@ -1458,6 +1486,7 @@ pulls.required_status_check_missing=Certains contrรดles requis sont manquants. pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requรชte de pull. pulls.blocked_by_approvals=Cette demande d'ajout n'a pas assez d'approbation. %d sur %d approbations accordรฉes. pulls.blocked_by_rejection=Cette demande de fusion a des modifications demandรฉes par un rรฉviseur officiel. +pulls.blocked_by_official_review_requests=Cette demande d'ajout a des demandes de revue officielles. pulls.blocked_by_outdated_branch=Cette demande d'ajout est bloquรฉe car elle est obsolรจte. pulls.blocked_by_changed_protected_files_1=Cette demande d'ajout est bloquรฉe car elle modifie un fichier protรฉgรฉ : pulls.blocked_by_changed_protected_files_n=Cette Pull Request est bloquรฉe car elle modifie les fichiers protรฉgรฉs : @@ -1496,6 +1525,7 @@ pulls.rebase_conflict_summary=Message d'erreur pulls.unrelated_histories=ร‰chec de la fusion: La tรชte de fusion et la base ne partagent pas d'historique commun. Indice : Essayez une stratรฉgie diffรฉrente pulls.merge_out_of_date=ร‰chec de la fusion: La base a รฉtรฉ mise ร  jour en cours de fusion. Indice : Rรฉessayez. pulls.push_rejected_summary=Message de rejet complet +pulls.push_rejected_no_message=ร‰chec de la fusionย : La poussรฉe a รฉtรฉ rejetรฉe mais il n'y avait pas de message distant.
Revoyez les Git Hooks pour ce dรฉpot pulls.open_unmerged_pull_exists=`Vous ne pouvez pas rรฉ-ouvrir cette demande de fusion car il y a une demande de fusion (#%d) en attente avec des propriรฉtรฉs identiques.` pulls.status_checking=Certains contrรดles sont en attente pulls.status_checks_success=Tous les contrรดles ont rรฉussi @@ -1675,7 +1705,7 @@ settings.collaboration.write=ร‰criture settings.collaboration.read=Lecture settings.collaboration.owner=Propriรฉtaire settings.collaboration.undefined=Indรฉfini -settings.hooks=Dรฉclencheurs Web +settings.hooks=Webhooks settings.githooks=Dรฉclencheurs Git settings.basic_settings=Paramรจtres de base settings.mirror_settings=Rรฉglages Miroir @@ -1798,13 +1828,13 @@ settings.search_team=Rechercher une รฉquipeโ€ฆ settings.change_team_permission_tip=La permission de l'รฉquipe est dรฉfinie sur la page de configuration de l'รฉquipe et ne peut pas รชtre modifiรฉe par dรฉpรดt settings.delete_team_tip=Cette รฉquipe a accรจs ร  tous les dรฉpรดts et ne peut pas รชtre supprimรฉe settings.remove_team_success=L'accรจs de l'รฉquipe au dรฉpรดt a รฉtรฉ supprimรฉ. -settings.add_webhook=Ajouter un dรฉclencheur Web +settings.add_webhook=Ajouter un Webhook settings.add_webhook.invalid_channel_name=Le nom du canal Webhook ne peut pas รชtre vide et ne peut pas contenir seulement un caractรจre #. settings.hooks_desc=Les Webhooks font automatiquement des requรชtes HTTP POST ร  un serveur lorsque certains รฉvรฉnements Gitea se dรฉclenchent. Lire la suite dans le guide des Webhooks. settings.webhook_deletion=Retirer le Webhook settings.webhook_deletion_desc=Supprimer un webhook supprime ses paramรจtres et son historique. Continuer ? settings.webhook_deletion_success=Le webhook a รฉtรฉ supprimรฉ. -settings.webhook.test_delivery=Tester la version +settings.webhook.test_delivery=Tester l'envoi settings.webhook.test_delivery_desc=Testez ce webhook avec un faux รฉvรฉnement. settings.webhook.request=Requรชte settings.webhook.response=Rรฉponse @@ -1819,7 +1849,7 @@ settings.add_webhook_desc=Gitea enverra ร  l'URL cible des requรชtes POST< settings.payload_url=URL cible settings.http_method=Mรฉthode HTTP settings.content_type=Type de contenu POST -settings.secret=Confidentiel +settings.secret=Secret settings.slack_username=Nom d'utilisateur settings.slack_icon_url=URL de l'icรดne settings.discord_username=Nom d'utilisateur @@ -1829,19 +1859,19 @@ settings.event_push_only=ร‰vรฉnements de poussรฉe settings.event_send_everything=Tous les รฉvรฉnements settings.event_choose=ร‰vรฉnements personnalisรฉsโ€ฆ settings.event_header_repository=ร‰vรฉnements du dรฉpรดt -settings.event_create=Crรฉer -settings.event_create_desc=Branche ou Tag crรฉรฉ. -settings.event_delete=Supprimer -settings.event_delete_desc=Branche ou รฉtiquette supprimรฉ. +settings.event_create=Crรฉation +settings.event_create_desc=Branche ou รฉtiquette crรฉรฉ. +settings.event_delete=Suppression +settings.event_delete_desc=Branche ou รฉtiquette supprimรฉe. settings.event_fork=Bifurcation settings.event_fork_desc=Dรฉpรดt bifurquรฉ. settings.event_release=Version settings.event_release_desc=Version publiรฉe, mise ร  jour ou supprimรฉe dans un dรฉpรดt. -settings.event_push=Pousser +settings.event_push=Poussรฉe settings.event_push_desc=Git push vers un dรฉpรดt. settings.event_repository=Dรฉpรดt settings.event_repository_desc=Dรฉpรดt crรฉรฉ ou supprimรฉ. -settings.event_header_issue=ร‰vรฉnements du ticket +settings.event_header_issue=ร‰vรฉnements des tickets settings.event_issues=Tickets settings.event_issues_desc=Ticket ouvert, fermรฉ, rรฉ-ouvert ou modifiรฉ. settings.event_issue_assign=Ticket assignรฉ @@ -1849,7 +1879,7 @@ settings.event_issue_assign_desc=Ticket assignรฉ ou non assignรฉ. settings.event_issue_label=ร‰tiquettes des tickets settings.event_issue_label_desc=ร‰tiquettes de ticket mises ร  jour ou effacรฉes. settings.event_issue_milestone=Ticket jalonnรฉe -settings.event_issue_milestone_desc=Ticket jalonnรฉe ou dรฉ-jalonnรฉe. +settings.event_issue_milestone_desc=Ticket jalonnรฉ ou dรฉ-jalonnรฉ. settings.event_issue_comment=Commentaire du ticket settings.event_issue_comment_desc=Commentaire du ticket crรฉรฉ, modifiรฉ, ou supprimรฉ. settings.event_header_pull_request=ร‰vรฉnements de demande d'ajout @@ -2055,7 +2085,7 @@ release.new_subheader=Les versions organisent les versions publiรฉes du projet. release.edit_subheader=Les versions organisent les versions publiรฉes du projet. release.tag_name=Nom du tag release.target=Cible -release.tag_helper=Choisissez un tag existant ou crรฉez un nouveau tag. +release.tag_helper=Choisissez une รฉtiquette existante ou crรฉez une nouvelle รฉtiquette. release.title=Titre release.content=Contenu release.prerelease_desc=Marquer comme prรฉ-version @@ -2065,12 +2095,12 @@ release.publish=Publier release.save_draft=Sauvegarder le Brouillon release.edit_release=Modifier la version release.delete_release=Supprimer cette version -release.delete_tag=Supprimer le tag +release.delete_tag=Supprimer l'รฉtiquette release.deletion=Supprimer cette version release.deletion_success=Cette livraison a รฉtรฉ supprimรฉe. release.deletion_tag_success=L'รฉtiquette a รฉtรฉ supprimรฉe. -release.tag_name_already_exist=Une version avec ce nom de balise existe dรฉjร . -release.tag_name_invalid=Le nom de balise est invalide. +release.tag_name_already_exist=Une version avec ce nom d'รฉtiquette existe dรฉjร . +release.tag_name_invalid=Le nom de l'รฉtiquette est invalide. release.tag_already_exist=Ce nom d'รฉtiquette existe dรฉjร . release.downloads=Tรฉlรฉchargements release.download_count=Tรฉlรฉcharger: %s @@ -2090,7 +2120,7 @@ branch.create_from=de '%s' branch.create_success=La branche "%s" a รฉtรฉ crรฉe. branch.branch_already_exists=La branche '%s' existe dรฉjร  dans ce dรฉpรดt. branch.branch_name_conflict=Le nom de la branche ยซย %sย ยป est en conflit avec une branche existante ยซย %sย ยป. -branch.tag_collision=La branche '%s' ne peut รชtre crรฉรฉe comme une balise car un nom identique existe dรฉjร  dans le dรฉpรดt. +branch.tag_collision=La branche '%s' ne peut รชtre crรฉรฉe comme une รฉtiquette avec un nom identique existe dรฉjร  dans le dรฉpรดt. branch.deleted_by=Supprimรฉe par %s branch.restore_success=La branche "%s" a รฉtรฉ restaurรฉe. branch.restore_failed=La restauration de la branche '%s' a รฉchouรฉ. @@ -2165,7 +2195,7 @@ settings.delete_prompt=Cette organisation sera supprimรฉe dรฉfinitivement. Cette settings.confirm_delete_account=Confirmez la suppression settings.delete_org_title=Supprimer l'organisation settings.delete_org_desc=Cette organisation sera supprimรฉe dรฉfinitivement. Voulez-vous continuer ? -settings.hooks_desc=Vous pouvez ajouter des dรฉclencheurs qui seront activรฉs pour tous les dรฉpรดts de cette organisation. +settings.hooks_desc=Vous pouvez ajouter des webhooks qui seront activรฉs pour tous les dรฉpรดts de cette organisation. settings.labels_desc=Ajouter des รฉtiquettes qui peuvent รชtre utilisรฉes sur les tickets pour tous les dรฉpรดts dans cette organisation. @@ -2374,6 +2404,7 @@ repos.forks=Bifurcations repos.issues=Tickets repos.size=Taille +packages.published=Publiรฉs systemhooks=Rappels systรจme @@ -2672,9 +2703,9 @@ notices.system_notice_list=Informations notices.view_detail_header=Voir les dรฉtails de l'information systรจme notices.actions=Actions notices.select_all=Tout Sรฉlectionner -notices.deselect_all=Tous dรฉselectionner +notices.deselect_all=Tout dรฉsรฉlectionner notices.inverse_selection=Inverser la sรฉlection -notices.delete_selected=Supprimรฉ les รฉlรฉments sรฉlectionnรฉs +notices.delete_selected=Supprimer les รฉlรฉments sรฉlectionnรฉs notices.delete_all=Supprimer toutes les notifications notices.type=Type notices.type_1=Dรฉpรดt @@ -2700,6 +2731,7 @@ compare_commits_general=Comparer les rรฉvisions mirror_sync_delete=a synchronisรฉ puis supprimรฉ la nouvelle rรฉfรฉrence %[2]s vers %[3]s depuis le miroir approve_pull_request=`a approuvรฉ %[3]s#%[2]s` reject_pull_request=`a suggรฉrรฉs des changements pour %[3]s#%[2]s` +publish_release=`a publiรฉ "%[4]s" ร  %[3]s` review_dismissed_reason=Raison : [tool] @@ -2758,4 +2790,7 @@ error.unit_not_allowed=Vous n'รชtes pas autorisรฉ ร  accรฉder ร  cette section d [packages] empty.repo=Avez-vous tรฉlรฉchargรฉ un paquet, mais il n'est pas affichรฉ ici? Allez dans les paramรจtres du paquet et liez le ร  ce dรฉpรดt. +published_by_in=%[1]s publiรฉ par %[3]s en %[5]s +rubygems.required.ruby=Nรฉcessite la version de Ruby +rubygems.required.rubygems=Nรฉcessite la version de RubyGem diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index c996aef38..bacaff945 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -216,6 +216,7 @@ code_no_results=Nincs talรกlat a keresรฉsi kifejezรฉsedre. code_search_results=Keresรฉsi talรกlatok "%s" code_last_indexed_at=Utoljรกra indexelve: %s + [auth] create_new_account=Regisztrรกciรณ register_helper_msg=Van mรกr felhasznรกlรณi fiรณkja? Jelentkezzen be! diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index e7ddd418c..39818b81e 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -206,6 +206,7 @@ org_no_results=Tidak ada organisasi yang cocok ditemukan. code_no_results=Tidak ada kode sumber yang cocok dengan istilah yang anda cari. code_search_results=Hasil pencarian untuk '%s' + [auth] create_new_account=Daftar Akun register_helper_msg=Sudah memiliki akun? Masuk sekarang! diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 90979837c..eda95c1b6 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -238,6 +238,7 @@ org_no_results=Engar samsvarandi stofnanir fundust. code_no_results=Enginn samsvarandi frumkรณรฐi fannst eftur รพรญnum leitarorรฐum. code_search_results=Leitarniรฐurstรถรฐur fyrir โ€ž%sโ€œ + [auth] create_new_account=Skrรก Notanda register_helper_msg=Ertu nรบ รพegar meรฐ notanda? Skrรกรฐu รพig inn nรบna! diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index ac29c5b84..027c7e057 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -278,6 +278,7 @@ code_no_results=Nessun codice sorgente corrispondente ai termini di ricerca. code_search_results=Risultati di ricerca per '%s' code_last_indexed_at=Ultimo indicizzato %s + [auth] create_new_account=Registra un account register_helper_msg=Hai giร  un account? Accedi ora! diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index efb41ddd8..ade323eca 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -277,6 +277,9 @@ org_no_results=ไธ€่‡ดใ™ใ‚‹็ต„็น”ใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใ€‚ code_no_results=ๆคœ็ดขใƒฏใƒผใƒ‰ใซไธ€่‡ดใ™ใ‚‹ใ‚ฝใƒผใ‚นใ‚ณใƒผใƒ‰ใŒ่ฆ‹ใคใ‹ใ‚Šใพใ›ใ‚“ใ€‚ code_search_results='%s' ใฎๆคœ็ดข็ตๆžœ code_last_indexed_at=ๆœ€็ต‚ๅ–ๅพ— %s +relevant_repositories_tooltip=ใƒ•ใ‚ฉใƒผใ‚ฏใƒชใƒใ‚ธใƒˆใƒชใ‚„ใ€ใƒˆใƒ”ใƒƒใ‚ฏใ€ใ‚ขใ‚คใ‚ณใƒณใ€่ชฌๆ˜Žใฎใ„ใšใ‚Œใ‚‚็„กใ„ใƒชใƒใ‚ธใƒˆใƒชใฏ่กจ็คบใ•ใ‚Œใพใ›ใ‚“ใ€‚ +relevant_repositories=ๅฆฅๅฝ“ใจๆ€ใ‚ใ‚Œใ‚‹ใƒชใƒใ‚ธใƒˆใƒชใฎใฟใ‚’่กจ็คบใ—ใฆใ„ใพใ™ใ€‚ ใƒ•ใ‚ฃใƒซใ‚ฟใƒชใƒณใ‚ฐใ—ใชใ„็ตๆžœใ‚’่กจ็คบใ€‚ + [auth] create_new_account=ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‚’็™ป้Œฒ @@ -1035,6 +1038,13 @@ file_view_rendered=ใƒฌใƒณใƒ€ใƒชใƒณใ‚ฐ่กจ็คบ file_view_raw=Rawใƒ‡ใƒผใ‚ฟใ‚’่ฆ‹ใ‚‹ file_permalink=ใƒ‘ใƒผใƒžใƒชใƒณใ‚ฏ file_too_large=ใ“ใฎใƒ•ใ‚กใ‚คใƒซใฏๅคงใใ™ใŽใ‚‹ใŸใ‚ใ€่กจ็คบใงใใพใ›ใ‚“ใ€‚ +invisible_runes_header=`ใ“ใฎใƒ•ใ‚กใ‚คใƒซใซใฏไธๅฏ่ฆ–ใฎUnicodeๆ–‡ๅญ—ใŒๅซใพใ‚Œใฆใ„ใพใ™๏ผ` +invisible_runes_description=`ใ“ใฎใƒ•ใ‚กใ‚คใƒซใซใฏไธๅฏ่ฆ–Unicodeๆ–‡ๅญ—ใŒๅซใพใ‚ŒใฆใŠใ‚Šใ€ไธ‹ใซ่ฆ‹ใˆใฆใ„ใ‚‹ใ‚‚ใฎใจใฏ็•ฐใชใ‚‹ๅ‡ฆ็†ใŒ่กŒใ‚ใ‚Œใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ ใ‚ใชใŸใฎใƒฆใƒผใ‚นใ‚ฑใƒผใ‚นใŒๆ„ๅ›ณ็š„ใ‹ใคๆญฃๅฝ“ใชๅ ดๅˆใฏใ“ใฎ่ญฆๅ‘Šใ‚’็„ก่ฆ–ใ—ใฆๆง‹ใ„ใพใ›ใ‚“ใ€‚ ไธๅฏ่ฆ–ๆ–‡ๅญ—ใ‚’่กจ็คบใ™ใ‚‹ใซใฏใ‚จใ‚นใ‚ฑใƒผใƒ—ใƒœใ‚ฟใƒณใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚` +ambiguous_runes_header=`ใ“ใฎใƒ•ใ‚กใ‚คใƒซใซใฏๆ›–ๆ˜ง(ambiguous)ใชUnicodeๆ–‡ๅญ—ใŒๅซใพใ‚Œใฆใ„ใพใ™๏ผ` +ambiguous_runes_description=`ใ“ใฎใƒ•ใ‚กใ‚คใƒซใซใฏๆ›–ๆ˜ง(ambiguous)ใชUnicodeๆ–‡ๅญ—ใŒๅซใพใ‚ŒใฆใŠใ‚Šใ€ใ‚ใชใŸใŒไฝฟ็”จใ—ใฆใ„ใ‚‹ใƒญใ‚ฑใƒผใƒซใซใŠใ„ใฆไป–ใฎๆ–‡ๅญ—ใจๆททๅŒใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ ใ‚ใชใŸใฎใƒฆใƒผใ‚นใ‚ฑใƒผใ‚นใŒๆ„ๅ›ณ็š„ใ‹ใคๆญฃๅฝ“ใชๅ ดๅˆใฏใ“ใฎ่ญฆๅ‘Šใ‚’็„ก่ฆ–ใ—ใฆๆง‹ใ„ใพใ›ใ‚“ใ€‚ ใใ‚Œใ‚‰ใฎๆ–‡ๅญ—ใ‚’ใƒใ‚คใƒฉใ‚คใƒˆใ™ใ‚‹ใซใฏใ‚จใ‚นใ‚ฑใƒผใƒ—ใƒœใ‚ฟใƒณใ‚’ไฝฟ็”จใ—ใพใ™ใ€‚` +invisible_runes_line=`ใ“ใฎ่กŒใซใฏไธๅฏ่ฆ–ใฎUnicodeๆ–‡ๅญ—ใŒใ‚ใ‚Šใพใ™` +ambiguous_runes_line=`ใ“ใฎ่กŒใซใฏๆ›–ๆ˜ง(ambiguous)ใชUnicodeๆ–‡ๅญ—ใŒใ‚ใ‚Šใพใ™` +ambiguous_character=`%[1]c [U+%04[1]X] ใฏ %[2]c [U+%04[2]X] ใจๆททๅŒใ™ใ‚‹ใŠใใ‚ŒใŒใ‚ใ‚Šใพใ™` escape_control_characters=ใ‚จใ‚นใ‚ฑใƒผใƒ— unescape_control_characters=ใ‚จใ‚นใ‚ฑใƒผใƒ—่งฃ้™ค @@ -2888,6 +2898,7 @@ monitor.queue.nopool.title=ใƒฏใƒผใ‚ซใƒผใƒ—ใƒผใƒซใฏใ‚ใ‚Šใพใ›ใ‚“ monitor.queue.nopool.desc=ใ“ใฎใ‚ญใƒฅใƒผใฏไป–ใฎใ‚ญใƒฅใƒผใ‚’ใƒฉใƒƒใƒ—ใ—ใ€ใ“ใ‚Œ่‡ชไฝ“ใซใฏใƒฏใƒผใ‚ซใƒผใƒ—ใƒผใƒซใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ monitor.queue.wrapped.desc=wrappedใ‚ญใƒฅใƒผใฏใ€ใ™ใใซ้–‹ๅง‹ใ•ใ‚Œใชใ„ใ‚ญใƒฅใƒผใ‚’ใƒฉใƒƒใƒ—ใ—ใ€ๅ…ฅใฃใฆใใŸใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ใƒใƒฃใƒณใƒใƒซใซใƒใƒƒใƒ•ใ‚กใƒชใƒณใ‚ฐใ—ใพใ™ใ€‚ ใ“ใ‚Œ่‡ชไฝ“ใซใฏใƒฏใƒผใ‚ซใƒผใƒ—ใƒผใƒซใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ monitor.queue.persistable-channel.desc=persistable-channelใ‚ญใƒฅใƒผใฏไบŒใคใฎใ‚ญใƒฅใƒผใ‚’ใƒฉใƒƒใƒ—ใ—ใพใ™ใ€‚ ไธ€ใคใฏchannelใ‚ญใƒฅใƒผใงใ€่‡ชๅˆ†ใฎใƒฏใƒผใ‚ซใƒผใƒ—ใƒผใƒซใ‚’ๆŒใกใพใ™ใ€‚ใ‚‚ใ†ไธ€ใคใฏlevelใ‚ญใƒฅใƒผใงใ€ๅ‰ๅ›žใฎใ‚ทใƒฃใƒƒใƒˆใƒ€ใ‚ฆใƒณใ‹ใ‚‰ใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅผ•ใ็ถ™ใใŸใ‚ใฎใ‚‚ใฎใงใ™ใ€‚ ใ“ใ‚Œ่‡ชไฝ“ใซใฏใƒฏใƒผใ‚ซใƒผใƒ—ใƒผใƒซใŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ +monitor.queue.flush=ๆŽƒใๅ‡บใ—ใƒฏใƒผใ‚ซใƒผ monitor.queue.pool.timeout=ใ‚ฟใ‚คใƒ ใ‚ขใ‚ฆใƒˆ monitor.queue.pool.addworkers.title=ใƒฏใƒผใ‚ซใƒผใฎ่ฟฝๅŠ  monitor.queue.pool.addworkers.submit=ใƒฏใƒผใ‚ซใƒผใ‚’่ฟฝๅŠ  @@ -3120,6 +3131,8 @@ rubygems.dependencies.development=้–‹็™บ็”จไพๅญ˜้–ขไฟ‚ rubygems.required.ruby=ๅฟ…่ฆใชRubyใƒใƒผใ‚ธใƒงใƒณ rubygems.required.rubygems=ๅฟ…่ฆใชRubyGemใƒใƒผใ‚ธใƒงใƒณ rubygems.documentation=RubyGemsใƒฌใ‚ธใ‚นใƒˆใƒชใฎ่ฉณ็ดฐใซใคใ„ใฆใฏใ€ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆ ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ +vagrant.install=Vagrant ใƒœใƒƒใ‚ฏใ‚นใ‚’่ฟฝๅŠ ใ™ใ‚‹ใซใฏใ€ๆฌกใฎใ‚ณใƒžใƒณใƒ‰ใ‚’ๅฎŸ่กŒใ—ใพใ™ใ€‚ +vagrant.documentation=Vagrantใƒฌใ‚ธใ‚นใƒˆใƒชใฎ่ฉณ็ดฐใซใคใ„ใฆใฏ ใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ settings.link=ใ“ใฎใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใ‚’ใƒชใƒใ‚ธใƒˆใƒชใซใƒชใƒณใ‚ฏ settings.link.description=ใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใ‚’ใƒชใƒใ‚ธใƒˆใƒชใซใƒชใƒณใ‚ฏใ™ใ‚‹ใจใ€ใƒชใƒใ‚ธใƒˆใƒชใฎใƒ‘ใƒƒใ‚ฑใƒผใ‚ธใƒชใ‚นใƒˆใซ่กจ็คบใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚ settings.link.select=ใƒชใƒใ‚ธใƒˆใƒชใ‚’้ธๆŠž diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index d4917f861..e80eea95f 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -201,6 +201,7 @@ org_no_results=์ผ์น˜ํ•˜๋Š” ์กฐ์ง์ด ์—†์Šต๋‹ˆ๋‹ค. code_no_results=๊ฒ€์ƒ‰์–ด์™€ ์ผ์น˜ํ•˜๋Š” ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. code_search_results='%s'์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ + [auth] create_new_account=๊ณ„์ • ๋“ฑ๋ก register_helper_msg=์ด๋ฏธ ๊ณ„์ •์„ ๊ฐ€์ง€๊ณ  ๊ณ„์‹ ๊ฐ€์š”? ๋กœ๊ทธ์ธํ•˜์„ธ์š”! diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index b82675762..5cc532363 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -278,6 +278,7 @@ code_no_results=Netika atrasts pirmkods, kas atbilstu kritฤ“rijiem. code_search_results=Meklฤ“ลกanas rezultฤti '%s' code_last_indexed_at=Pฤ“dฤ“jo reizi indeksฤ“ts %s + [auth] create_new_account=Reฤฃistrฤ“t kontu register_helper_msg=Jau ir konts? Pieraksties tagad! diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini index 7ee595bf4..6474abc59 100644 --- a/options/locale/locale_ml-IN.ini +++ b/options/locale/locale_ml-IN.ini @@ -187,6 +187,7 @@ org_no_results=เดชเตŠเดฐเตเดคเตเดคเดชเตเดชเต†เดŸเตเดจเตเดจ เดธเด‚เด˜เดŸเดจ code_no_results=เดจเดฟเด™เตเด™เดณเตเดŸเต† เดคเดฟเดฐเดฏเตฝ เดชเดฆเดตเตเดฎเดพเดฏเดฟ เดชเตŠเดฐเตเดคเตเดคเดชเตเดชเต†เดŸเตเดจเตเดจ เดธเต‹เดดเตเดธเต เด•เต‹เดกเตเด•เดณเตŠเดจเตเดจเตเด‚ เด•เดฃเตเดŸเต†เดคเตเดคเดพเดจเดพเดฏเดฟเดฒเตเดฒ. code_search_results=%s เดŽเดจเตเดจเดคเดฟเดจเดพเดฏเตเดณเตเดณ เดคเดฟเดฐเดฏเตฝ เดซเดฒเด™เตเด™เตพ + [auth] create_new_account=เด…เด•เตเด•เต—เดฃเตเดŸเต เดฐเดœเดฟเดธเตเดฑเตเดฑเตผ เดšเต†เดฏเตเดฏเตเด• register_helper_msg=เด‡เดคเดฟเดจเด•เด‚ เด’เดฐเต เด…เด•เตเด•เต—เดฃเตเดŸเต เด‰เดฃเตเดŸเต‡เดพ? เด‡เดชเตเดชเต‹เตพ เดชเตเดฐเดตเต‡เดถเดฟเด•เตเด•เตเด•! diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 5b18185fe..9bcb0f7c7 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -278,6 +278,7 @@ code_no_results=Geen broncode gevonden in overeenstemming met uw zoekterm. code_search_results=Zoekresultaten voor โ€˜%sโ€™ code_last_indexed_at=Laatst geรฏndexeerd %s + [auth] create_new_account=Account registreren register_helper_msg=Heeft u al een account? Klik hier om in te loggen diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 840f69d93..5abf069c5 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -273,6 +273,7 @@ code_no_results=Nie znaleziono kodu ลบrรณdล‚owego odpowiadajฤ…cego Twojej frazie code_search_results=Wyniki wyszukiwania dla '%s' code_last_indexed_at=Ostatnio indeksowane %s + [auth] create_new_account=Zarejestruj konto register_helper_msg=Masz juลผ konto? Zaloguj siฤ™ teraz! diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index b5c81702d..d291e7f1b 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -277,6 +277,8 @@ org_no_results=Nenhuma organizaรงรฃo correspondente foi encontrada. code_no_results=Nenhum cรณdigo-fonte correspondente ao seu termo de pesquisa foi encontrado. code_search_results=Resultados da pesquisa por: '%s' code_last_indexed_at=รšltima indexaรงรฃo %s +relevant_repositories=Apenas repositรณrios relevantes estรฃo sendo mostrados, mostrar resultados nรฃo filtrados. + [auth] create_new_account=Cadastrar conta @@ -1035,6 +1037,7 @@ file_view_rendered=Ver Renderizado file_view_raw=Ver original file_permalink=Link permanente file_too_large=O arquivo รฉ muito grande para ser mostrado. +invisible_runes_header=`Este arquivo contรฉm caracteres Unicode invisรญveis!` escape_control_characters=Escapar unescape_control_characters=Desescapar @@ -1055,6 +1058,7 @@ normal_view=Visรฃo normal line=linha lines=linhas +editor.add_file=Adicionar Arquivo editor.new_file=Novo arquivo editor.upload_file=Enviar arquivo editor.edit_file=Editar arquivo @@ -1220,6 +1224,7 @@ issues.new.add_reviewer_title=Solicitar revisรฃo issues.choose.get_started=Primeiros passos issues.choose.blank=Padrรฃo issues.choose.blank_about=Criar uma issue a partir do modelo padrรฃo. +issues.choose.ignore_invalid_templates=Modelos invรกlidos foram ignorados issues.no_ref=Nenhum branch/tag especificado issues.create=Criar issue issues.new_label=Nova etiqueta @@ -1260,6 +1265,8 @@ issues.filter_milestone=Marco issues.filter_milestone_no_select=Todos os marcos issues.filter_assignee=Atribuรญdo issues.filter_assginee_no_select=Todos os responsรกveis +issues.filter_poster=Autor +issues.filter_poster_no_select=Todos os autores issues.filter_type=Tipo issues.filter_type.all_issues=Todas as issues issues.filter_type.assigned_to_you=Atribuรญdos a vocรช @@ -1797,6 +1804,7 @@ settings.tracker_issue_style=Formato de nรบmero do issue tracker externo settings.tracker_issue_style.numeric=Numรฉrico settings.tracker_issue_style.alphanumeric=Alfanumรฉrico settings.tracker_issue_style.regexp=Expressรฃo Regular +settings.tracker_issue_style.regexp_pattern=Padrรฃo de expressรฃo regular settings.tracker_url_format_desc=Use os espaรงos reservados {user}, {repo} e {index} para o nome de usuรกrio, nome do repositรณrio e o รญndice de problemas. settings.enable_timetracker=Habilitar Cronรดmetro settings.allow_only_contributors_to_track_time=Permitir que apenas os colaboradores acompanhem o contador de tempo @@ -2769,8 +2777,10 @@ config.skip_tls_verify=Ignorar verificaรงรฃo de TLS config.mailer_config=Configuraรงรฃo de Envio de E-mail config.mailer_enabled=Habilitado +config.mailer_enable_helo=Ativar HELO config.mailer_name=Nome config.mailer_protocol=Protocolo +config.mailer_smtp_addr=Addr SMTP config.mailer_smtp_port=Porta SMTP config.mailer_user=Usuรกrio config.mailer_use_sendmail=Usar o Sendmail @@ -3078,6 +3088,8 @@ npm.dependencies.development=Dependรชncias de Desenvolvimento npm.dependencies.peer=Dependรชncias Peer npm.dependencies.optional=Dependรชncias Opcionais npm.details.tag=Tag +pub.details.repository_site=Site do Repositรณrio +pub.details.documentation_site=Site da Documentaรงรฃo pypi.requires=Requer Python pypi.install=Para instalar o pacote usando pip, execute o seguinte comando: pypi.documentation=Para obter mais informaรงรตes sobre o registro PyPI, consulte a documentaรงรฃo. diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index de7935e78..611ef8b40 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -277,6 +277,9 @@ org_no_results=Nรฃo foram encontradas quaisquer organizaรงรตes correspondentes. code_no_results=Nรฃo foi encontrado qualquer cรณdigo-fonte correspondente ร  sua pesquisa. code_search_results=Resultados da pesquisa para '%s' code_last_indexed_at=รšltima indexaรงรฃo %s +relevant_repositories_tooltip=Repositรณrios que sรฃo derivaรงรตes ou que nรฃo tรชm tรณpico, nem รญcone, nem descriรงรฃo, estรฃo escondidos. +relevant_repositories=Apenas estรฃo a ser mostrados os repositรณrios relevantes. Mostrar resultados nรฃo filtrados. + [auth] create_new_account=Fazer inscriรงรฃo @@ -1228,6 +1231,8 @@ issues.new.add_reviewer_title=Solicitar revisรฃo issues.choose.get_started=Comeรงar issues.choose.blank=Padrรฃo issues.choose.blank_about=Cria uma questรฃo a partir do modelo padrรฃo. +issues.choose.ignore_invalid_templates=Modelos invรกlidos foram ignorados +issues.choose.invalid_templates=Foram encontrados %v modelos invรกlidos issues.no_ref=Sem ramo ou etiqueta especificados issues.create=Criar questรฃo issues.new_label=Novo rรณtulo @@ -3128,6 +3133,8 @@ rubygems.dependencies.development=Dependรชncias de desenvolvimento rubygems.required.ruby=Requer a versรฃo do Ruby rubygems.required.rubygems=Requer a versรฃo do RubyGem rubygems.documentation=Para obter mais informaรงรตes sobre o registo do RubyGems, consulte a documentaรงรฃo. +vagrant.install=Para adicionar uma mรกquina virtual Vagrant, execute o seguinte comando: +vagrant.documentation=Para obter mais informaรงรตes sobre o registo do Vagrant, consulte a documentaรงรฃo. settings.link=Vincular este pacote a um repositรณrio settings.link.description=Se vocรช vincular um pacote a um repositรณrio, o pacote serรก listado na lista de pacotes do repositรณrio. settings.link.select=Escolha o repositรณrio diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index a185fe0cb..348fa7432 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -274,6 +274,7 @@ code_no_results=ะกะพะพั‚ะฒะตั‚ัั‚ะฒัƒัŽั‰ะธะน ะฟะพะธัะบะพะฒะพะผัƒ ะทะฐะฟั€ะพั code_search_results=ะ ะตะทัƒะปัŒั‚ะฐั‚ั‹ ะฟะพะธัะบะฐ ะดะปั '%s' code_last_indexed_at=ะŸะพัะปะตะดะฝะธะน ะฟั€ะพะธะฝะดะตะบัะธั€ะพะฒะฐะฝะฝั‹ะน %s + [auth] create_new_account=ะ ะตะณะธัั‚ั€ะฐั†ะธั ะฐะบะบะฐัƒะฝั‚ะฐ register_helper_msg=ะฃะถะต ะตัั‚ัŒ ะฐะบะบะฐัƒะฝั‚? ะะฒั‚ะพั€ะธะทัƒะนั‚ะตััŒ! diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 7e7b140f2..9d19176da 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -241,6 +241,7 @@ code_no_results=เถ”เถถเถœเทš เทƒเท™เท€เท”เถธเทŠ เถดเถฏเถบ เถœเทเถฝเถดเท™เถฑ เถด code_search_results='%s' เทƒเถณเท„เท เทƒเท™เท€เท”เถธเทŠ เถดเทŠโ€เถปเถญเท’เถตเถฝ code_last_indexed_at=เถ…เท€เทƒเถฑเทŠ เทƒเท”เถ เท’เถœเถญ %s + [auth] create_new_account=เถœเท’เถซเท”เถธเถšเทŠ เถฝเท’เถบเทเถดเถฏเท’เถ‚เถ เท’ เถšเถปเถฑเทŠเถฑ register_helper_msg=เถฏเทเถฑเถงเถธเถญเทŠ เถœเท’เถซเท”เถธเถšเทŠ เถญเท’เถถเทšเถฏ? เถฏเทเถฑเทŠเถธ เถดเท”เถปเถฑเถบ เท€เถฑเทŠเถฑ! diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 00d1034fc..f1d1872df 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -224,6 +224,7 @@ code_no_results=Ingen kรคllkod hittades som matchar din sรถkterm. code_search_results=Sรถktresultat fรถr '%s' code_last_indexed_at=Indexerades senast %s + [auth] create_new_account=Registrera Konto register_helper_msg=Har du redan ett konto? Logga in nu! diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index d92c46eae..465c14b35 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -277,6 +277,9 @@ org_no_results=EลŸleลŸen organizasyon bulunamadฤฑ. code_no_results=Aranan terimlerle eลŸleลŸen bir kaynak kod bulunamadฤฑ. code_search_results='%s' iรงin arama sonuรงlarฤฑ code_last_indexed_at=Son endekslenen %s +relevant_repositories_tooltip=ร‡atal olan veya konusu, simgesi veya aรงฤฑklamasฤฑ olmayan depolar gizlenmiลŸtir. +relevant_repositories=Sadece iliลŸkili depolar gรถsteriliyor, filtrelenmemiลŸ sonuรงlarฤฑ gรถster. + [auth] create_new_account=Hesap OluลŸtur @@ -3128,6 +3131,8 @@ rubygems.dependencies.development=GeliลŸtirme BaฤŸฤฑmlฤฑlฤฑklarฤฑ rubygems.required.ruby=Gereken Ruby sรผrรผmรผ rubygems.required.rubygems=Gereken RubyGem sรผrรผmรผ rubygems.documentation=RubyGems kรผtรผฤŸรผ hakkฤฑnda daha fazla bilgi iรงin, belgeye bakabilirsiniz. +vagrant.install=Vagrant paketi eklemek iรงin aลŸaฤŸฤฑdaki komutu รงalฤฑลŸtฤฑrฤฑn: +vagrant.documentation=Vagrant kรผtรผฤŸรผ hakkฤฑnda daha fazla bilgi iรงin, belgeye bakabilirsiniz. settings.link=Bu paketi bir depoya baฤŸlayฤฑn settings.link.description=EฤŸer bir paketi bir depoya baฤŸlarsanฤฑz, paket deponun paket listesinde listelenecektir. settings.link.select=Depo Seรง diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index bed92be4f..f71ef1fa7 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -257,6 +257,7 @@ code_no_results=ะ’ั–ะดะฟะพะฒั–ะดะฝะธะน ะฟะพัˆัƒะบะพะฒะพะผัƒ ะทะฐะฟะธั‚ะฐะฝะฝัŽ code_search_results=ะ ะตะทัƒะปัŒั‚ะฐั‚ะธ ะฟะพัˆัƒะบัƒ '%s' code_last_indexed_at=ะžัั‚ะฐะฝะฝั– ั–ะฝะดะตะบัะพะฒะฐะฝั– %s + [auth] create_new_account=ะ ะตั”ัั‚ั€ะฐั†ั–ั ะพะฑะปั–ะบะพะฒะพะณะพ ะทะฐะฟะธััƒ register_helper_msg=ะ’ะถะต ะทะฐั€ะตั”ัั‚ั€ะพะฒะฐะฝั–? ะฃะฒั–ะนะดั–ั‚ัŒ ะทะฐั€ะฐะท! diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index fd0a6a8b4..997899a90 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -278,6 +278,7 @@ code_no_results=ๆœชๆ‰พๅˆฐไธŽๆœ็ดขๅญ—่ฏๅŒน้…็š„ๆบไปฃ็ ใ€‚ code_search_results=โ€œ%sโ€ ็š„ๆœ็ดข็ป“ๆžœๆ˜ฏ code_last_indexed_at=ๆœ€ๅŽ็ดขๅผ•ไบŽ %s + [auth] create_new_account=ๆณจๅ†Œๅธๅท register_helper_msg=ๅทฒ็ปๆณจๅ†Œ๏ผŸ็ซ‹ๅณ็™ปๅฝ•๏ผ @@ -3054,7 +3055,7 @@ filter.type.all=ๆ‰€ๆœ‰ filter.no_result=ๆ‚จ็š„่ฟ‡ๆปคๅ™จๆฒกๆœ‰ไบง็”Ÿไปปไฝ•็ป“ๆžœใ€‚ filter.container.tagged=ๅทฒๅŠ ๆ ‡็ญพ filter.container.untagged=ๆœชๅŠ ๆ ‡็ญพ -published_by=ไบŽ %[1]s ๅ‘ๅธƒไบ† %[3]s +published_by=็”ฑ %[3]s ๅ‘ๅธƒไบŽ %[1]s published_by_in=%[3]s ไบŽ %[1]s ๅ‘ๅธƒไบ† %[5]s installation=ๅฎ‰่ฃ… about=ๅ…ณไบŽ่ฟ™ไธช่ฝฏไปถๅŒ… @@ -3128,6 +3129,8 @@ rubygems.dependencies.development=ๅผ€ๅ‘ไพ่ต– rubygems.required.ruby=้œ€่ฆ Ruby ็‰ˆๆœฌ rubygems.required.rubygems=้œ€่ฆ RubyGem ็‰ˆๆœฌ rubygems.documentation=ๅ…ณไบŽ RubyGems ๆณจๅ†Œไธญๅฟƒ็š„ๆ›ดๅคšไฟกๆฏ๏ผŒ่ฏทๅ‚้˜… ๆ–‡ๆกฃใ€‚ +vagrant.install=่‹ฅ่ฆๆทปๅŠ ไธ€ไธช Vagrant box๏ผŒ่ฏท่ฟ่กŒไปฅไธ‹ๅ‘ฝไปค๏ผš +vagrant.documentation=ๅ…ณไบŽ Vagrant ๆณจๅ†Œไธญๅฟƒ็š„ๆ›ดๅคšไฟกๆฏ๏ผŒ่ฏทๅ‚้˜… ๆ–‡ๆกฃใ€‚ settings.link=ๅฐ†ๆญค่ฝฏไปถๅŒ…้“พๆŽฅๅˆฐไป“ๅบ“ settings.link.description=ๅฆ‚ๆžœๆ‚จๅฐ†ไธ€ไธช่ฝฏไปถๅŒ…ไธŽไธ€ไธชไปฃ็ ๅบ“้“พๆŽฅ่ตทๆฅ๏ผŒ่ฝฏไปถๅŒ…ๅฐ†ๆ˜พ็คบๅœจไปฃ็ ๅบ“็š„่ฝฏไปถๅŒ…ๅˆ—่กจไธญใ€‚ settings.link.select=้€‰ๆ‹ฉไป“ๅบ“ diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 18168c1db..0aa7cff23 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -89,6 +89,7 @@ users=ไฝฟ็”จ่€… organizations=็ต„็น” search=ๆœๅฐ‹ + [auth] register_helper_msg=ๅทฒ็ถ“่จปๅ†Š๏ผŸ็ซ‹ๅณ็™ป้Œ„๏ผ forgot_password_title=ๅฟ˜่จ˜ๅฏ†็ขผ diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 47f8ffcdf..55d3456ef 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -108,7 +108,7 @@ rss_feed=RSS ๆ‘˜่ฆ [error] occurred=็™ผ็”Ÿ้Œฏ่ชค -report_message=ๅฆ‚ๆžœๆ‚จ็ขบๅฎš้€™ๆ˜ฏไธ€ๅ€‹ Gitea ็š„ bug๏ผŒ่ซ‹ๅˆฐ GitHub ๆœๅฐ‹็›ธ้—œ็š„ๅ•้กŒ๏ผŒๅฆ‚ๆžœๆœ‰้œ€่ฆๆ‚จไนŸๅฏไปฅๅปบ็ซ‹ๆ–ฐๅ•้กŒใ€‚ +report_message=ๅฆ‚ๆžœๆ‚จ็ขบๅฎš้€™ๆ˜ฏ Gitea ็š„ bug๏ผŒ่ซ‹ๅˆฐ GitHub ๆœๅฐ‹็›ธ้—œ็š„ๅ•้กŒ๏ผŒๅฆ‚ๆžœๆœ‰้œ€่ฆๆ‚จไนŸๅฏไปฅๅปบ็ซ‹ๆ–ฐๅ•้กŒใ€‚ missing_csrf=้Œฏ่ชค็š„่ซ‹ๆฑ‚๏ผšๆœชๆไพ› CSRF token invalid_csrf=้Œฏ่ชค็š„่ซ‹ๆฑ‚๏ผš็„กๆ•ˆ็š„ CSRF token not_found=ๆ‰พไธๅˆฐ็›ฎๆจ™ใ€‚ @@ -178,6 +178,8 @@ log_root_path_helper=ๆ—ฅ่ชŒๆช”ๅฐ‡ๅฏซๅ…ฅๆญค็›ฎ้Œ„ใ€‚ optional_title=ๅฏ้ธ่จญๅฎš email_title=้›ปๅญ้ƒตไปถ่จญๅฎš +smtp_addr=SMTP ไธปๆฉŸ +smtp_port=SMTP ้€ฃๆŽฅๅŸ  smtp_from=้›ปๅญ้ƒตไปถๅฏ„ไปถ่€… smtp_from_helper=Gitea ๅฐ‡ๆœƒไฝฟ็”จ็š„้›ปๅญไฟก็ฎฑ๏ผŒ็›ดๆŽฅ่ผธๅ…ฅ้›ปๅญไฟก็ฎฑๆˆ–ไฝฟ็”จใ€Œ"ๅ็จฑ" ใ€็š„ๆ ผๅผใ€‚ mailer_user=SMTP ๅธณ่™Ÿ @@ -276,6 +278,7 @@ code_no_results=ๆ‰พไธๅˆฐ็ฌฆๅˆๆ‚จ้—œ้ตๅญ—็š„ๅŽŸๅง‹็ขผใ€‚ code_search_results=ใ€Œ%sใ€็š„ๆœๅฐ‹็ตๆžœ code_last_indexed_at=ๆœ€ๅพŒ็ดขๅผ• %s + [auth] create_new_account=่จปๅ†Šๅธณๆˆถ register_helper_msg=ๅทฒ็ถ“ๆœ‰ๅธณๆˆถไบ†๏ผŸ็ซ‹ๅณ็™ปๅ…ฅ๏ผ @@ -797,6 +800,7 @@ email_notifications.enable=ๅ•Ÿ็”จ้ƒตไปถ้€š็Ÿฅ email_notifications.onmention=ๅชๅœจ่ขซๆๅˆฐๆ™‚ๅ‚ณ้€้ƒตไปถ้€š็Ÿฅ email_notifications.disable=้—œ้–‰้ƒตไปถ้€š็Ÿฅ email_notifications.submit=ๅฅ—็”จ้ƒตไปถๅๅฅฝ่จญๅฎš +email_notifications.andyourown=ๅ’Œๆ‚จ่‡ชๅทฑ็š„้€š็Ÿฅ visibility=ไฝฟ็”จ่€…็€่ฆฝๆฌŠ้™ visibility.public=ๅ…ฌ้–‹ @@ -930,6 +934,7 @@ form.name_pattern_not_allowed=ๅ„ฒๅญ˜ๅบซๅ็จฑไธๅฏๅŒ…ๅซๅญ—ๅ…ƒใ€Œ%sใ€ใ€‚ need_auth=ๆŽˆๆฌŠ migrate_options=้ท็งป้ธ้ … migrate_service=้ท็งปๆœๅ‹™ +migrate_options_mirror_helper=ๅฐ‡ๆญคๅ„ฒๅญ˜ๅบซ่จญๅฎš็‚บ้กๅƒ migrate_options_lfs=้ท็งป LFS ๆช”ๆกˆ migrate_options_lfs_endpoint.label=LFS ็ซฏ้ปž migrate_options_lfs_endpoint.description=้ท็งปๅฐ‡ๆœƒๅ˜—่ฉฆไฝฟ็”จๆ‚จ็š„ Git Remote ไพ†็ขบ่ช LFS ไผบๆœๅ™จใ€‚ๅฆ‚ๆžœๅญ˜ๅ„ฒๅบซ็š„ LFS ่ณ‡ๆ–™ๆ”พๅœจๅ…ถไป–ๅœฐๆ–น๏ผŒๆ‚จไนŸๅฏไปฅๆŒ‡ๅฎš่‡ช่จ‚็š„็ซฏ้ปžใ€‚ @@ -1031,6 +1036,13 @@ file_view_rendered=ๆชข่ฆ–ๆธฒๆŸ“ๅœ– file_view_raw=ๆŸฅ็œ‹ๅŽŸๅง‹ๆ–‡ไปถ file_permalink=ๆฐธไน…้€ฃ็ต file_too_large=ๆช”ๆกˆๅคชๅคง๏ผŒ็„กๆณ•้กฏ็คบใ€‚ +invisible_runes_header=`ๆญคๆช”ๆกˆๅซๆœ‰็œ‹ไธ่ฆ‹็š„ Unicode ๅญ—ๅ…ƒ๏ผ` +invisible_runes_description=`ๆญคๆช”ๆกˆๅซๆœ‰็œ‹ไธ่ฆ‹็š„ Unicode ๅญ—ๅ…ƒ๏ผŒ้€™ไบ›ๅญ—ๅ…ƒ็š„่™•็†ๆ–นๅผๅฏ่ƒฝๅ’Œไธ‹้ขๅ‘ˆ็พ็š„ไธๅŒใ€‚่‹ฅๆ‚จๆ˜ฏๆœ‰ๆ„ไธ”ๅˆ็†็š„ไฝฟ็”จ๏ผŒๆ‚จๅฏไปฅๆ”พๅฟƒๅœฐๅฟฝ็•ฅๆญค่ญฆๅ‘Šใ€‚ไฝฟ็”จ Escape ๆŒ‰้ˆ•้กฏ็คบ้šฑ่—็š„ๅญ—ๅ…ƒใ€‚` +ambiguous_runes_header=`ๆญคๆช”ๆกˆๅซๆœ‰ๆ˜“ๆททๆท†็š„ Unicode ๅญ—ๅ…ƒ๏ผ` +ambiguous_runes_description=`ๆญคๆช”ๆกˆๅซๆœ‰ๆ˜“ๆททๆท†็š„ Unicode ๅญ—ๅ…ƒ๏ผŒ้€™ไบ›ๅญ—ๅ…ƒ็š„่™•็†ๆ–นๅผๅฏ่ƒฝๅ’Œไธ‹้ขๅ‘ˆ็พ็š„ไธๅŒใ€‚่‹ฅๆ‚จๆ˜ฏๆœ‰ๆ„ไธ”ๅˆ็†็š„ไฝฟ็”จ๏ผŒๆ‚จๅฏไปฅๆ”พๅฟƒๅœฐๅฟฝ็•ฅๆญค่ญฆๅ‘Šใ€‚ไฝฟ็”จ Escape ๆŒ‰้ˆ•ๆจ™่จ˜้€™ไบ›ๅญ—ๅ…ƒใ€‚` +invisible_runes_line=`้€™ไธ€่กŒๆœ‰็œ‹ไธ่ฆ‹็š„ Unicode ๅญ—ๅ…ƒ` +ambiguous_runes_line=`้€™ไธ€่กŒๆœ‰ๆ˜“ๆททๆท†็š„ Unicode ๅญ—ๅ…ƒ` +ambiguous_character=`%[1]c [U+%04[1]X] ๅฎนๆ˜“่ˆ‡ %[2]c [U+%04[2]X] ๆททๆท†` escape_control_characters=Escape unescape_control_characters=Unescape @@ -1051,13 +1063,14 @@ normal_view=ๆจ™ๆบ–ๆชข่ฆ– line=่กŒ lines=่กŒ -editor.new_file=ๆ–ฐๅขžๆ–‡ไปถ -editor.upload_file=ไธŠๅ‚ณๆ–‡ไปถ -editor.edit_file=็ทจ่ผฏๆ–‡ไปถ +editor.add_file=ๅŠ ๅ…ฅๆช”ๆกˆ +editor.new_file=ๆ–ฐๅขžๆช”ๆกˆ +editor.upload_file=ไธŠๅ‚ณๆช”ๆกˆ +editor.edit_file=็ทจ่ผฏๆช”ๆกˆ editor.preview_changes=้ ่ฆฝๆ›ดๆ”น editor.cannot_edit_lfs_files=็„กๆณ•ๅœจ web ไป‹้ขไธญ็ทจ่ผฏ LFS ๆช”ใ€‚ editor.cannot_edit_non_text_files=็ถฒ็ซ™ไป‹้ขไธ่ƒฝ็ทจ่ผฏไบŒ้€ฒไฝๆช”ๆกˆ -editor.edit_this_file=็ทจ่ผฏๆ–‡ไปถ +editor.edit_this_file=็ทจ่ผฏๆช”ๆกˆ editor.this_file_locked=ๆช”ๆกˆๅทฒ่ขซ้Ž–ๅฎš editor.must_be_on_a_branch=ไฝ ๅฟ…้ ˆๅœจไธ€ๅ€‹ๅˆ†ๆ”ฏๆˆ–ๆๅ‡บๅฐๆญคๆช”็š„ๆ›ดๆ”นใ€‚ editor.fork_before_edit=ๅฆ‚ๆžœไฝ ๆƒณ่ฆๅฐ้€™ๅ€‹ๆช”ๆกˆ้€ฒ่กŒๆˆ–ๆๅ‡บไฟฎๆ”น๏ผŒ่ซ‹ๅ…ˆ fork ้€™ๅ€‹ๅ„ฒๅญ˜ๅบซใ€‚ @@ -1256,6 +1269,8 @@ issues.filter_milestone=้‡Œ็จ‹็ข‘ issues.filter_milestone_no_select=ๆ‰€ๆœ‰้‡Œ็จ‹็ข‘ issues.filter_assignee=่ฒ ่ฒฌไบบ issues.filter_assginee_no_select=ๆ‰€ๆœ‰่ฒ ่ฒฌไบบ +issues.filter_poster=ไฝœ่€… +issues.filter_poster_no_select=ๆ‰€ๆœ‰ไฝœ่€… issues.filter_type=้กžๅž‹ issues.filter_type.all_issues=ๆ‰€ๆœ‰ๅ•้กŒ issues.filter_type.assigned_to_you=ๆŒ‡ๆดพ็ตฆๆ‚จ็š„ @@ -1410,6 +1425,7 @@ issues.due_date_form_remove=็งป้™ค issues.due_date_not_writer=ๆ‚จ้œ€่ฆๅ„ฒๅญ˜ๅบซๅฏซๅ…ฅๆฌŠ้™ไพ†ๆ›ดๆ”นๅ•้กŒ็š„ๆˆชๆญขๆ—ฅใ€‚ issues.due_date_not_set=ๆœช่จญๅฎšๆˆชๆญขๆ—ฅๆœŸใ€‚ issues.due_date_added=ๆ–ฐๅขžไบ†ๆˆชๆญขๆ—ฅๆœŸ %s %s +issues.due_date_modified=ๅฐ‡ๆˆชๆญขๆ—ฅๆœŸๅพž %[2]s ไฟฎๆ”น็‚บ %[1]s %[3]s issues.due_date_remove=็งป้™คไบ†ๆˆชๆญขๆ—ฅๆœŸ %s %s issues.due_date_overdue=้€พๆœŸ issues.due_date_invalid=ๆˆชๆญขๆ—ฅๆœŸ็„กๆ•ˆๆˆ–่ถ…ๅ‡บ็ฏ„ๅœ๏ผŒ่ซ‹ไฝฟ็”จใ€Œyyyy-mm-ddใ€็š„ๆ ผๅผใ€‚ @@ -1521,6 +1537,8 @@ pulls.remove_prefix=็งป้™ค %s ๅ‰็ถด pulls.data_broken=ๆญคๅˆไฝต่ซ‹ๆฑ‚ๅทฒๆๆฏ€๏ผŒๅ› ็‚บ้บๅคฑ Fork ่ณ‡่จŠใ€‚ pulls.files_conflicted=ๆญคๅˆไฝต่ซ‹ๆฑ‚ๆœ‰่ฎŠๆ›ดๅ’Œ็›ฎๆจ™ๅˆ†ๆ”ฏ่ก็ชใ€‚ pulls.is_checking=ๆญฃๅœจ้€ฒ่กŒๅˆไฝต่ก็ชๆชขๆŸฅ๏ผŒ่ซ‹็จๅพŒๅ†่ฉฆใ€‚ +pulls.is_ancestor=้€™ๅ€‹ๅˆ†ๆ”ฏๅทฒ็ถ“ๅˆไฝตๅˆฐ็›ฎๆจ™ๅˆ†ๆ”ฏไธŠใ€‚ๆฒ’ๆœ‰ๅฏไปฅๅˆไฝต็š„ๅ…งๅฎนใ€‚ +pulls.is_empty=ๅœจ้€™ๅ€‹ๅˆ†ๆ”ฏไธŠ็š„ๆ›ดๅ‹•้ƒฝๅทฒ็ถ“ๅฅ—็”จๅœจ็›ฎๆจ™ๅˆ†ๆ”ฏไธŠใ€‚้€™ๅฐ‡ๆœƒ็”ข็”Ÿไธ€ๅ€‹็ฉบ็š„ๆไบคใ€‚ pulls.required_status_check_failed=ๆœช้€š้ŽๆŸไบ›ๅฟ…่ฆ็š„ๆชขๆŸฅใ€‚ pulls.required_status_check_missing=้บๅคฑๆŸไบ›ๅฟ…่ฆ็š„ๆชขๆŸฅใ€‚ pulls.required_status_check_administrator=่บซ็‚บ็ณป็ตฑ็ฎก็†ๅ“ก๏ผŒๆ‚จไพ็„ถๅฏไปฅ้€ฒ่กŒๅˆไฝตใ€‚ @@ -2064,7 +2082,7 @@ settings.block_on_official_review_requests=ๆœ‰ๅฎ˜ๆ–น็š„ๅฏฉๆ ธ่ซ‹ๆฑ‚ๆ™‚้˜ปๆ“‹ๅˆ settings.block_on_official_review_requests_desc=ๅฆ‚ๆžœๆœ‰ๅฎ˜ๆ–น็š„ๅฏฉๆ ธ่ซ‹ๆฑ‚ๆ™‚๏ผŒๅณไฝฟๆœ‰่ถณๅค ็š„ๆ ธๅฏไนŸไธๅ…่จฑ้€ฒ่กŒๅˆไฝตใ€‚ settings.block_outdated_branch=ๅฆ‚ๆžœๅˆไฝต่ซ‹ๆฑ‚ๅทฒ็ถ“้Žๆ™‚ๅ‰‡้˜ปๆ“‹ๅˆไฝต settings.block_outdated_branch_desc=็•ถ head ๅˆ†ๆ”ฏ่ฝๅพŒๆ–ผๅŸบ็คŽๅˆ†ๆ”ฏๆ™‚ไธๅพ—ๅˆไฝตใ€‚ -settings.default_branch_desc=่ซ‹้ธๆ“‡ไธ€ๅ€‹็”จไพ†ๆไบค็จ‹ๅผ็ขผๅ’Œๅˆไฝต่ซ‹ๆฑ‚็š„้ ่จญๅˆ†ๆ”ฏใ€‚ +settings.default_branch_desc=่ซ‹้ธๆ“‡็”จไพ†ๆไบค็จ‹ๅผ็ขผๅ’Œๅˆไฝต่ซ‹ๆฑ‚็š„้ ่จญๅˆ†ๆ”ฏใ€‚ settings.default_merge_style_desc=ๅˆไฝต่ซ‹ๆฑ‚็š„้ ่จญๆ–นๅผ๏ผš settings.choose_branch=้ธๆ“‡ไธ€ๅ€‹ๅˆ†ๆ”ฏ... settings.no_protected_branch=ๆฒ’ๆœ‰ๅ—ไฟ่ญท็š„ๅˆ†ๆ”ฏใ€‚ @@ -2523,6 +2541,8 @@ users.delete_account=ๅˆช้™คไฝฟ็”จ่€…ๅธณๆˆถ users.cannot_delete_self=ๆ‚จ็„กๆณ•ๅˆช้™คๆ‚จ่‡ชๅทฑ users.still_own_repo=้€™ๅ€‹ไฝฟ็”จ่€…้‚„ๆ“ๆœ‰ไธ€ๅ€‹ๆˆ–ๆ›ดๅคš็š„ๅ„ฒๅญ˜ๅบซใ€‚่ซ‹ๅ…ˆๅˆช้™คๆˆ–ๆ˜ฏ่ฝ‰็งป้€™ไบ›ๅ„ฒๅญ˜ๅบซใ€‚ users.still_has_org=ๆญคไฝฟ็”จ่€…ๆ˜ฏ็ต„็น”็š„ๆˆๅ“กใ€‚่ซ‹ๅ…ˆๅฐ‡ไป–ๅพž็ต„็น”ไธญ็งป้™คใ€‚ +users.purge=ๆธ…้™คไฝฟ็”จ่€… +users.purge_help=ๅผทๅˆถๅˆช้™คไฝฟ็”จ่€…ๅ’Œไป–ๆ“ๆœ‰็š„ๆ‰€ๆœ‰ๅ„ฒๅญ˜ๅบซใ€็ต„็น”ใ€ๅฅ—ไปถ๏ผŒๆ‰€ๆœ‰็•™่จ€ไนŸๆœƒ่ขซๅˆช้™คใ€‚ users.still_own_packages=ๆญคไฝฟ็”จ่€…ๆ“ๆœ‰ไธ€ๅ€‹ๆˆ–ๅคšๅ€‹ๅฅ—ไปถ๏ผŒ่ซ‹ๅ…ˆๅˆช้™ค้€™ไบ›ๅฅ—ไปถใ€‚ users.deletion_success=ไฝฟ็”จ่€…ๅธณๆˆถๅทฒ่ขซๅˆช้™คใ€‚ users.reset_2fa=้‡่จญๅ…ฉๆญฅ้ฉŸ้ฉ—่ญ‰ @@ -2779,13 +2799,19 @@ config.queue_length=ไฝ‡ๅˆ—้•ทๅบฆ config.deliver_timeout=ๅ‚ณ้€้€พๆ™‚ config.skip_tls_verify=็•ฅ้Ž TLS ้ฉ—่ญ‰ +config.mailer_config=้ƒตไปถ็จ‹ๅผ็ต„ๆ…‹ config.mailer_enabled=ๅ•Ÿ็”จๆœๅ‹™ +config.mailer_enable_helo=ๅ•Ÿ็”จ HELO config.mailer_name=็™ผ้€่€…ๅ็จฑ +config.mailer_protocol=ๅ”ๅฎš +config.mailer_smtp_addr=SMTP ไฝๅ€ +config.mailer_smtp_port=SMTP ้€ฃๆŽฅๅŸ  config.mailer_user=็™ผ้€่€…ๅธณ่™Ÿ config.mailer_use_sendmail=ไฝฟ็”จ Sendmail config.mailer_sendmail_path=Sendmail ่ทฏๅพ‘ config.mailer_sendmail_args=Sendmail ๅƒๆ•ธ config.mailer_sendmail_timeout=Sendmail ้€พๆ™‚ +config.mailer_use_dummy=Dummy config.test_email_placeholder=้›ปๅญไฟก็ฎฑ (ไพ‹๏ผštest@example.com) config.send_test_mail=ๅ‚ณ้€ๆธฌ่ฉฆ้ƒตไปถ config.test_mail_failed=ๅ‚ณ้€ๆธฌ่ฉฆ้ƒตไปถๅˆฐใ€Œ%sใ€ๆ™‚ๅคฑๆ•—๏ผš%v @@ -2870,6 +2896,7 @@ monitor.queue.nopool.title=ๆฒ’ๆœ‰ๅทฅไฝœ่€…้›†ๅ€ monitor.queue.nopool.desc=ๆญคไฝ‡ๅˆ—ๅŒ…่ฃ่‘—ๅ…ถไป–ไฝ‡ๅˆ—๏ผŒไธ”ๆœฌ่บซๆฒ’ๆœ‰ๅทฅไฝœ่€…้›†ๅ€ใ€‚ monitor.queue.wrapped.desc=ไธ€ๅ€‹่ขซๅŒ…่ฃ็š„ไฝ‡ๅˆ—ๅŒ…่ฃ่‘—ไธ€ๅ€‹็ทฉๆ…ขๅ•Ÿๅ‹•็š„ไฝ‡ๅˆ—๏ผŒๅœจ Channel ไธญ็ทฉ่ก่ซ‹ๆฑ‚ใ€‚ๅฎƒๆœฌ่บซๆฒ’ๆœ‰ๅทฅไฝœ่€…้›†ๅ€ใ€‚ monitor.queue.persistable-channel.desc=ไธ€ๅ€‹ๆŒไน…ๆ€ง็š„ Channel ๅŒ…่ฃ่‘—ๅ…ฉๅ€‹ๅˆ—้šŠใ€‚ไธ€ๅ€‹ๆ“ๆœ‰่‡ชๅทฑๅทฅไฝœ่€…้›†ๅ€็š„ Channel ไฝ‡ๅˆ—๏ผŒๅฆไธ€ๅ€‹ๆ˜ฏ Level ไฝ‡ๅˆ—็”จๆ–ผๅ…ˆๅ‰้—œ้–‰ๅพŒๆŒ็บŒ็š„่ซ‹ๆฑ‚ใ€‚ๅฎƒๆœฌ่บซๆฒ’ๆœ‰ๅทฅไฝœ่€…้›†ๅ€ใ€‚ +monitor.queue.flush=ๆธ…้™ค่€… monitor.queue.pool.timeout=้€พๆ™‚ monitor.queue.pool.addworkers.title=ๆ–ฐๅขžๅทฅไฝœ่€… monitor.queue.pool.addworkers.submit=ๆ–ฐๅขžๅทฅไฝœ่€… @@ -3022,6 +3049,7 @@ title=ๅฅ—ไปถ desc=็ฎก็†ๅ„ฒๅญ˜ๅบซๅฅ—ไปถใ€‚ empty=็›ฎๅ‰้‚„ๆฒ’ๆœ‰ๅฅ—ไปถใ€‚ empty.documentation=้—œๆ–ผๅฅ—ไปถ่จปๅ†Šไธญๅฟƒ็š„่ฉณๆƒ…่ซ‹ๅƒ้–ฑ่ชชๆ˜Žๆ–‡ไปถใ€‚ +empty.repo=ๅทฒ็ถ“ไธŠๅ‚ณไบ†ไธ€ๅ€‹ๅฅ—ไปถ๏ผŒไฝ†ๆ˜ฏๆฒ’ๆœ‰้กฏ็คบๅœจ้€™่ฃกๅ—Ž๏ผŸๆ‰“้–‹ๅฅ—ไปถ่จญๅฎšไธฆๅฐ‡ๅ…ถ้€ฃ็ตๅˆฐ้€™ๅ€‹ๅ„ฒๅญ˜ๅบซใ€‚ filter.type=้กžๅž‹ filter.type.all=ๆ‰€ๆœ‰ filter.no_result=ๆฒ’ๆœ‰็ฏฉ้ธ็ตๆžœใ€‚ @@ -3087,6 +3115,10 @@ npm.dependencies.development=้–‹็™ผ็›ธไพๆ€ง npm.dependencies.peer=Peer ็›ธไพๆ€ง npm.dependencies.optional=้ธ็”จ็›ธไพๆ€ง npm.details.tag=ๆจ™็ฑค +pub.install=ๅŸท่กŒไธ‹ๅˆ—ๅ‘ฝไปคไปฅไฝฟ็”จ Dart ๅฎ‰่ฃๆญคๅฅ—ไปถ: +pub.documentation=้—œๆ–ผ Pub registry ็š„่ฉณๆƒ…่ซ‹ๅƒ้–ฑ่ชชๆ˜Žๆ–‡ไปถใ€‚ +pub.details.repository_site=ๅ„ฒๅญ˜ๅบซ็ถฒ็ซ™ +pub.details.documentation_site=ๆ–‡ไปถ็ถฒ็ซ™ pypi.requires=้œ€่ฆ Python pypi.install=ๅŸท่กŒไธ‹ๅˆ—ๅ‘ฝไปคไปฅไฝฟ็”จ pip ๅฎ‰่ฃๆญคๅฅ—ไปถ: pypi.documentation=้—œๆ–ผ PyPI registry ็š„่ฉณๆƒ…่ซ‹ๅƒ้–ฑ่ชชๆ˜Žๆ–‡ไปถใ€‚ diff --git a/package-lock.json b/package-lock.json index aabbd84fd..ef534bf87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "dependencies": { "@claviska/jquery-minicolors": "2.3.6", "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", - "@primer/octicons": "17.4.0", + "@primer/octicons": "17.4.1", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", - "easymde": "2.16.1", + "easymde": "2.17.0", "esbuild-loader": "2.19.0", "escape-goat": "4.0.0", "fast-glob": "3.2.11", @@ -23,13 +23,13 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.3", + "mermaid": "9.1.6", "mini-css-extract-plugin": "2.6.1", - "monaco-editor": "0.33.0", + "monaco-editor": "0.34.0", "monaco-editor-webpack-plugin": "7.0.1", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.13.2", + "swagger-ui-dist": "4.14.0", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", @@ -46,20 +46,21 @@ "wrap-ansi": "8.0.1" }, "devDependencies": { - "@happy-dom/jest-environment": "6.0.4", - "@stoplight/spectral-cli": "6.5.0", - "eslint": "8.21.0", + "@playwright/test": "1.25.1", + "@stoplight/spectral-cli": "6.5.1", + "eslint": "8.22.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", - "eslint-plugin-sonarjs": "0.14.0", + "eslint-plugin-sonarjs": "0.15.0", "eslint-plugin-unicorn": "43.0.2", - "eslint-plugin-vue": "9.3.0", + "eslint-plugin-vue": "9.4.0", "jest": "28.1.3", - "jest-extended": "3.0.1", - "markdownlint-cli": "0.32.1", + "jest-environment-jsdom": "28.1.3", + "jest-extended": "3.0.2", + "markdownlint-cli": "0.32.2", "postcss-less": "6.0.0", - "stylelint": "14.9.1", - "stylelint-config-standard": "26.0.0", + "stylelint": "14.11.0", + "stylelint-config-standard": "28.0.0", "svgo": "2.8.0", "updates": "13.1.4" }, @@ -99,30 +100,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", - "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", + "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", - "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", + "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.10", + "@babel/generator": "^7.18.13", "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-module-transforms": "^7.18.9", "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.10", + "@babel/parser": "^7.18.13", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.10", - "@babel/types": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -147,12 +148,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz", - "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", + "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", "dev": true, "dependencies": { - "@babel/types": "^7.18.10", + "@babel/types": "^7.18.13", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -426,9 +427,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz", - "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -625,19 +626,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz", - "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", + "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.10", + "@babel/generator": "^7.18.13", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.18.9", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -655,9 +656,9 @@ } }, "node_modules/@babel/types": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", - "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", + "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.18.10", @@ -713,9 +714,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", - "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", "cpu": [ "loong64" ], @@ -769,20 +770,6 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/@happy-dom/jest-environment": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-6.0.4.tgz", - "integrity": "sha512-3FEWODVN4H7Hnkbm7IEtRE8lU7uitxSsnVagkQbfjjwKSUfF6BT9MJ95VF7nLimdc5ctOIa7ZbDietRRIpgSHw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "happy-dom": "^6.0.4", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", @@ -938,69 +925,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/console/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/console/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/console/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/@jest/core": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", @@ -1049,82 +973,19 @@ } } }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/core/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/core/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^27.5.1" + "jest-mock": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/expect": { @@ -1153,52 +1014,6 @@ } }, "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", - "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/types": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@jest/fake-timers": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", @@ -1215,86 +1030,15 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/types": { + "node_modules/@jest/globals": { "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@jest/globals/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -1344,69 +1088,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/reporters/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/@jest/schemas": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", @@ -1448,32 +1129,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@jest/test-sequencer": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", @@ -1515,7 +1170,7 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/transform/node_modules/@jest/types": { + "node_modules/@jest/types": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", @@ -1532,48 +1187,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/transform/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/transform/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -1631,9 +1244,9 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1744,19 +1357,35 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.1.tgz", + "integrity": "sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "playwright-core": "1.25.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@popperjs/core": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", - "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@primer/octicons": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz", - "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==", + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.1.tgz", + "integrity": "sha512-DPlnpsARphzx9+kQexKsfLafOa+3FL3MKxaIPxz/isXiiZWgOuNTV8awHZ2Mm1M45mPqsBerucrFE8z2zVCbrg==", "dependencies": { "object-assign": "^4.1.1" } @@ -1806,9 +1435,9 @@ "dev": true }, "node_modules/@sinclair/typebox": { - "version": "0.24.26", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz", - "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==", + "version": "0.24.28", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", + "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -1821,18 +1450,18 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0" } }, "node_modules/@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", "dev": true, "dependencies": { "jsonpointer": "^5.0.0", @@ -1933,9 +1562,9 @@ } }, "node_modules/@stoplight/spectral-cli": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz", - "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.1.tgz", + "integrity": "sha512-+qpwsDG2jQ4ULQmegBWonI3UnF6tUh351WDnV1GU8acl8eaeKbS+ZUNBgoP2f9tnMTfITdctVRFEGC3D6P7f9g==", "dev": true, "dependencies": { "@rollup/plugin-commonjs": "^20.0.0", @@ -1998,19 +1627,19 @@ } }, "node_modules/@stoplight/spectral-core": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz", - "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.0.tgz", + "integrity": "sha512-CJOudlFTajdOS+A4QBkjogFQCVzoVcKQzJ1HMkLGq4RHgu9D5cy5iiMbADMW5e/Ffew+dxs3PPAH29Y0gaEHGg==", "dev": true, "dependencies": { - "@stoplight/better-ajv-errors": "1.0.1", - "@stoplight/json": "~3.18.1", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "~3.20.1", "@stoplight/lifecycle": "2.3.2", "@stoplight/path": "1.3.2", "@stoplight/spectral-parsers": "^1.0.0", "@stoplight/spectral-ref-resolver": "^1.0.0", "@stoplight/spectral-runtime": "^1.0.0", - "@stoplight/types": "~13.2.0", + "@stoplight/types": "~13.6.0", "@types/es-aggregate-error": "^1.0.2", "@types/json-schema": "^7.0.11", "ajv": "^8.6.0", @@ -2032,13 +1661,14 @@ } }, "node_modules/@stoplight/spectral-core/node_modules/@stoplight/json": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz", - "integrity": "sha512-QmELAqBS8DC+8YuG7+OvDVP6RaUVi8bzN0KKW2UEcZg+0a1sqeeZgfW079AmJIZg8HEN7udAt4iozIB8Dm0t1Q==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", "dev": true, "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.2", - "@stoplight/types": "^13.0.0", + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", "jsonc-parser": "~2.2.1", "lodash": "^4.17.21", "safe-stable-stringify": "^1.1" @@ -2048,9 +1678,9 @@ } }, "node_modules/@stoplight/spectral-core/node_modules/@stoplight/types": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz", - "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==", + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -2076,17 +1706,16 @@ } }, "node_modules/@stoplight/spectral-functions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz", - "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.1.tgz", + "integrity": "sha512-UWeUrxc1pu45ZNYKtK3OloMpkUNTPqwpmjbGUn4oEnbqrLEYu/B2oOg66EtGcadOBEsdOb7f5vaPlhUNNrpEpQ==", "dev": true, "dependencies": { - "@stoplight/better-ajv-errors": "1.0.1", - "@stoplight/json": "~3.17.1", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.1", "@stoplight/spectral-core": "^1.7.0", "@stoplight/spectral-formats": "^1.0.0", "@stoplight/spectral-runtime": "^1.1.0", - "@stoplight/types": "12.3.0", "ajv": "^8.6.3", "ajv-draft-04": "~1.0.0", "ajv-errors": "~3.0.0", @@ -2099,13 +1728,14 @@ } }, "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/json": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.2.tgz", - "integrity": "sha512-NwIVzanXRUy291J5BMkncCZRMG1Lx+aq+VidGQgfkJjgo8vh1Y/PSAz7fSU8gVGSZBCcqmOkMI7R4zw7DlfTwA==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", "dev": true, "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.2", - "@stoplight/types": "^12.3.0", + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", "jsonc-parser": "~2.2.1", "lodash": "^4.17.21", "safe-stable-stringify": "^1.1" @@ -2114,21 +1744,64 @@ "node": ">=8.3.0" } }, - "node_modules/@stoplight/spectral-parsers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.1.tgz", - "integrity": "sha512-JGKlrTxhjUzIGo2FOCf8Qp0WKTWXedoRNPovqYPE8pAp08epqU8DzHwl/i46BGH5yfTmouKMZgBN/PV2+Cr5jw==", + "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", "dev": true, "dependencies": { - "@stoplight/json": "3.17.0", - "@stoplight/types": "12.3.0", - "@stoplight/yaml": "4.2.2", + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-parsers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.2.tgz", + "integrity": "sha512-ZQXknJ+BM5Re4Opj4cgVlHgG2qyOk/wznKJq3Vf1qsBEg2CNzN0pJmSB0deRqW0kArqm44qpb8c+cz3F2rgMtw==", + "dev": true, + "dependencies": { + "@stoplight/json": "~3.20.1", + "@stoplight/types": "^13.6.0", + "@stoplight/yaml": "~4.2.3", "tslib": "^2.3.1" }, "engines": { "node": ">=12" } }, + "node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/json": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", + "jsonc-parser": "~2.2.1", + "lodash": "^4.17.21", + "safe-stable-stringify": "^1.1" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, "node_modules/@stoplight/spectral-ref-resolver": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.1.tgz", @@ -2173,9 +1846,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-bundler/node_modules/@rollup/plugin-commonjs": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz", - "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz", + "integrity": "sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -2242,20 +1915,35 @@ "node": ">=8" } }, + "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/@stoplight/yaml": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.2.tgz", + "integrity": "sha512-N086FU8pmSpjc5TvMBjmlTniZVh3OXzmEh6SYljSLiuv6aMxgjyjf13YrAlUqgu0b4b6pQ5zmkjrfo9i0SiLsw==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.1", + "@stoplight/types": "^12.0.0", + "@stoplight/yaml-ast-parser": "0.0.48", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=10.8" + } + }, "node_modules/@stoplight/spectral-rulesets": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz", - "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.12.0.tgz", + "integrity": "sha512-ktSO5YPzYzscnGTQffyKJwrzsR2i5cpPUC4yBp0isc6mOeiVec4r9sjMUN1mJt0RVnXi509vd0+YlMthFIZYnw==", "dev": true, "dependencies": { "@asyncapi/specs": "^2.14.0", - "@stoplight/better-ajv-errors": "1.0.1", + "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.1", "@stoplight/spectral-formats": "^1.2.0", "@stoplight/spectral-functions": "^1.5.1", "@stoplight/spectral-runtime": "^1.1.1", - "@stoplight/types": "^12.5.0", + "@stoplight/types": "^13.6.0", "@types/json-schema": "^7.0.7", "ajv": "^8.8.2", "ajv-formats": "~2.1.0", @@ -2268,16 +1956,16 @@ } }, "node_modules/@stoplight/spectral-rulesets/node_modules/@stoplight/types": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", - "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" }, "engines": { - "node": ">=8" + "node": "^12.20 || >=14.13" } }, "node_modules/@stoplight/spectral-runtime": { @@ -2312,13 +2000,13 @@ } }, "node_modules/@stoplight/yaml": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.2.tgz", - "integrity": "sha512-N086FU8pmSpjc5TvMBjmlTniZVh3OXzmEh6SYljSLiuv6aMxgjyjf13YrAlUqgu0b4b6pQ5zmkjrfo9i0SiLsw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.3.tgz", + "integrity": "sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==", "dev": true, "dependencies": { "@stoplight/ordered-object-literal": "^1.0.1", - "@stoplight/types": "^12.0.0", + "@stoplight/types": "^13.0.0", "@stoplight/yaml-ast-parser": "0.0.48", "tslib": "^2.2.0" }, @@ -2332,18 +2020,31 @@ "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==", "dev": true }, + "node_modules/@stoplight/yaml/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, "node_modules/@swc/helpers": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.2.14.tgz", "integrity": "sha512-wpCQMhf5p5GhNg2MmGKXzUNwxe7zRiCsmqYsamez2beP7mKPCSiu+BjZcdN95yYSzO857kr0VfQewmGpS77nqA==" }, "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, "engines": { - "node": ">= 6" + "node": ">= 10" } }, "node_modules/@trysound/sax": { @@ -2388,9 +2089,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", + "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -2404,15 +2105,6 @@ "@types/tern": "*" } }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/es-aggregate-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz", @@ -2423,9 +2115,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", - "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2445,15 +2137,6 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -2487,6 +2170,17 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jsdom": { + "version": "16.2.15", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-16.2.15.tgz", + "integrity": "sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/parse5": "^6.0.3", + "@types/tough-cookie": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -2499,9 +2193,9 @@ "dev": true }, "node_modules/@types/marked": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.3.tgz", - "integrity": "sha512-HnMWQkLJEf/PnxZIfbm0yGJRRZYYMhb++O9M36UCTA9z53uPvVoSlAwJr3XOpDEryb7Hwl1qAx/MV6YIW1RXxg==" + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.6.tgz", + "integrity": "sha512-ITAVUzsnVbhy5afxhs4PPPbrv2hKVEDH5BhhaQNQlVG0UNu+9A18XSdYr53nBdHZ0ADEQLl+ciOjXbs7eHdiQQ==" }, "node_modules/@types/minimist": { "version": "1.2.2", @@ -2510,9 +2204,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", - "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -2526,16 +2220,16 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz", - "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", "dev": true }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "node_modules/@types/prettier": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", + "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, "node_modules/@types/stack-utils": { @@ -2552,6 +2246,12 @@ "@types/estree": "*" } }, + "node_modules/@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, "node_modules/@types/urijs": { "version": "1.19.19", "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz", @@ -2559,9 +2259,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", + "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -2800,6 +2500,12 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2823,6 +2529,28 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", @@ -2841,9 +2569,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -3080,12 +2808,6 @@ "printable-characters": "^1.0.42" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, "node_modules/ast-types": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", @@ -3263,6 +2985,12 @@ "node": ">=8" } }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, "node_modules/browserslist": { "version": "4.21.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", @@ -3380,9 +3108,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001373", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz", - "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==", + "version": "1.0.30001382", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz", + "integrity": "sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==", "funding": [ { "type": "opencollective", @@ -3394,12 +3122,6 @@ } ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3518,18 +3240,6 @@ "node": ">=0.10.0" } }, - "node_modules/clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "dependencies": { - "is-regexp": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -3541,9 +3251,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.7", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz", - "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A==" + "version": "5.65.8", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.8.tgz", + "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" }, "node_modules/codemirror-spell-checker": { "version": "1.1.2", @@ -3576,9 +3286,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, "node_modules/colorette": { @@ -3618,51 +3328,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/consolidate": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", @@ -3804,12 +3469,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3833,6 +3492,30 @@ "node": ">=8.0.0" } }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, "node_modules/d3": { "version": "7.6.1", "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz", @@ -4531,6 +4214,33 @@ "node": ">= 6" } }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", @@ -4584,6 +4294,12 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", + "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "dev": true + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -4657,6 +4373,88 @@ "node": ">=4" } }, + "node_modules/degenerator/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/degenerator/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/degenerator/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/degenerator/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/delaunator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", @@ -4769,6 +4567,18 @@ } ] }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", @@ -4785,9 +4595,9 @@ } }, "node_modules/dompurify": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz", - "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw==" + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", + "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" }, "node_modules/domutils": { "version": "2.8.0", @@ -4818,21 +4628,21 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/easymde": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz", - "integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.17.0.tgz", + "integrity": "sha512-xerjhBh6G+FDfU2EBfKNEVqawYGqnK2zACKtyQlZKnxPoaesncRbHiSX5Yrf3Ur8KjEX1BvG7Ysccrd8hKTkig==", "dependencies": { "@types/codemirror": "^5.60.4", "@types/marked": "^4.0.1", "codemirror": "^5.63.1", "codemirror-spell-checker": "1.1.2", - "marked": "^4.0.10" + "marked": "^4.0.18" } }, "node_modules/electron-to-chromium": { - "version": "1.4.210", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz", - "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==" + "version": "1.4.228", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.228.tgz", + "integrity": "sha512-XfDHCvou7CsDMlFwb0WZ1tWmW48e7Sn7VBRyPfZsZZila9esRsJl1trO+OqDNV97GggFSt0ISbWslKXfQkG//g==" }, "node_modules/emittery": { "version": "0.10.2", @@ -5011,9 +4821,9 @@ } }, "node_modules/esbuild": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz", - "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -5022,33 +4832,33 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/linux-loong64": "0.14.53", - "esbuild-android-64": "0.14.53", - "esbuild-android-arm64": "0.14.53", - "esbuild-darwin-64": "0.14.53", - "esbuild-darwin-arm64": "0.14.53", - "esbuild-freebsd-64": "0.14.53", - "esbuild-freebsd-arm64": "0.14.53", - "esbuild-linux-32": "0.14.53", - "esbuild-linux-64": "0.14.53", - "esbuild-linux-arm": "0.14.53", - "esbuild-linux-arm64": "0.14.53", - "esbuild-linux-mips64le": "0.14.53", - "esbuild-linux-ppc64le": "0.14.53", - "esbuild-linux-riscv64": "0.14.53", - "esbuild-linux-s390x": "0.14.53", - "esbuild-netbsd-64": "0.14.53", - "esbuild-openbsd-64": "0.14.53", - "esbuild-sunos-64": "0.14.53", - "esbuild-windows-32": "0.14.53", - "esbuild-windows-64": "0.14.53", - "esbuild-windows-arm64": "0.14.53" + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" } }, "node_modules/esbuild-android-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", - "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", "cpu": [ "x64" ], @@ -5061,9 +4871,9 @@ } }, "node_modules/esbuild-android-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", - "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", "cpu": [ "arm64" ], @@ -5076,9 +4886,9 @@ } }, "node_modules/esbuild-darwin-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", - "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", "cpu": [ "x64" ], @@ -5091,9 +4901,9 @@ } }, "node_modules/esbuild-darwin-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", - "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", "cpu": [ "arm64" ], @@ -5106,9 +4916,9 @@ } }, "node_modules/esbuild-freebsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", - "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", "cpu": [ "x64" ], @@ -5121,9 +4931,9 @@ } }, "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", - "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", "cpu": [ "arm64" ], @@ -5136,9 +4946,9 @@ } }, "node_modules/esbuild-linux-32": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", - "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", "cpu": [ "ia32" ], @@ -5151,9 +4961,9 @@ } }, "node_modules/esbuild-linux-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", - "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", "cpu": [ "x64" ], @@ -5166,9 +4976,9 @@ } }, "node_modules/esbuild-linux-arm": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", - "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", "cpu": [ "arm" ], @@ -5181,9 +4991,9 @@ } }, "node_modules/esbuild-linux-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", - "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", "cpu": [ "arm64" ], @@ -5196,9 +5006,9 @@ } }, "node_modules/esbuild-linux-mips64le": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", - "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", "cpu": [ "mips64el" ], @@ -5211,9 +5021,9 @@ } }, "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", - "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", "cpu": [ "ppc64" ], @@ -5226,9 +5036,9 @@ } }, "node_modules/esbuild-linux-riscv64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", - "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", "cpu": [ "riscv64" ], @@ -5241,9 +5051,9 @@ } }, "node_modules/esbuild-linux-s390x": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", - "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", "cpu": [ "s390x" ], @@ -5275,9 +5085,9 @@ } }, "node_modules/esbuild-netbsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", - "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", "cpu": [ "x64" ], @@ -5290,9 +5100,9 @@ } }, "node_modules/esbuild-openbsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", - "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", "cpu": [ "x64" ], @@ -5305,9 +5115,9 @@ } }, "node_modules/esbuild-sunos-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", - "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", "cpu": [ "x64" ], @@ -5320,9 +5130,9 @@ } }, "node_modules/esbuild-windows-32": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", - "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", "cpu": [ "ia32" ], @@ -5335,9 +5145,9 @@ } }, "node_modules/esbuild-windows-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", - "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", "cpu": [ "x64" ], @@ -5350,9 +5160,9 @@ } }, "node_modules/esbuild-windows-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", - "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", "cpu": [ "arm64" ], @@ -5396,13 +5206,13 @@ } }, "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "dependencies": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "estraverse": "^5.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1" }, @@ -5411,21 +5221,12 @@ "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=4.0" + "node": ">=6.0" }, "optionalDependencies": { "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/escodegen/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -5478,9 +5279,9 @@ } }, "node_modules/eslint": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz", - "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", + "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", "dev": true, "dependencies": { "@eslint/eslintrc": "^1.3.0", @@ -5553,16 +5354,20 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -5574,73 +5379,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-import": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", @@ -5705,9 +5443,9 @@ } }, "node_modules/eslint-plugin-sonarjs": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz", - "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.15.0.tgz", + "integrity": "sha512-LuxHdAe6VqSbi1phsUvNjbmXLuvlobmryQJJNyQYbdubCfz6K8tmgoqNiJPnz0pP2AbYDbtuPm0ajOMgMrC+dQ==", "dev": true, "engines": { "node": ">=12" @@ -5748,9 +5486,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz", - "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.4.0.tgz", + "integrity": "sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -5955,18 +5693,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "dependencies": { - "clone-regexp": "^2.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -5992,69 +5718,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/expect/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/expect/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/expect/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -6190,9 +5853,9 @@ } }, "node_modules/flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "node_modules/font-awesome": { @@ -6204,17 +5867,17 @@ } }, "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/fs-extra": { @@ -6342,15 +6005,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/get-source": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", @@ -6424,6 +6078,15 @@ "node": ">= 6" } }, + "node_modules/get-uri/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -6580,24 +6243,9 @@ } }, "node_modules/gsap": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.10.4.tgz", - "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" - }, - "node_modules/happy-dom": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-6.0.4.tgz", - "integrity": "sha512-b+ID23Ms0BY08UNLymsOMG7EI2jSlwEt4cbJs938GZfeNAg+fqgkSO3TokQMgSOFoHznpjWmpVjBUL5boJ9PWw==", - "dev": true, - "dependencies": { - "css.escape": "^1.5.1", - "he": "^1.2.0", - "node-fetch": "^2.x.x", - "sync-request": "^6.1.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0" - } + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.0.tgz", + "integrity": "sha512-TV5aFGqXht+0o/CelnhCikSe3QGeG+q1XA/fyFFsMzesILHgWgFWIz0NuXIgcMaL5h7MG2l+j0BTupS5YyYkrw==" }, "node_modules/hard-rejection": { "version": "2.1.0", @@ -6694,6 +6342,18 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -6712,21 +6372,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6744,12 +6389,12 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, "dependencies": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, @@ -6757,21 +6402,6 @@ "node": ">= 6" } }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -6923,9 +6553,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", - "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", "dev": true, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" @@ -7029,9 +6659,9 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dependencies": { "has": "^1.0.3" }, @@ -7143,6 +6773,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -7168,15 +6804,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", @@ -7411,123 +7038,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/jest-circus/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-cli": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", @@ -7562,49 +7072,6 @@ } } }, - "node_modules/jest-cli/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-cli/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-cli/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-config": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", @@ -7650,49 +7117,6 @@ } } }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-config/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-config/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-diff": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", @@ -7736,44 +7160,20 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-each/node_modules/@jest/types": { + "node_modules/jest-environment-jsdom": { "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-each/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-each/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-28.1.3.tgz", + "integrity": "sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==", "dev": true, "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", "@jest/types": "^28.1.3", + "@types/jsdom": "^16.2.4", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3", + "jsdom": "^19.0.0" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -7796,134 +7196,17 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-extended": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.1.tgz", - "integrity": "sha512-OSGbKUhbjy7QikfQyK3ishFrAqLeRodBzeJk7SuuWGACAT7HHcGuJ4aUQ3ueLANx4KSv1Pa7r1LJWGtJ3eI0xA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.2.tgz", + "integrity": "sha512-LnVZvwWLRV9AL8J7f4frKu0KHuTrbIFK15IqrvSwbFCYxalkuC5l7HfcofsksePrvlEJ2WAcfYNnu1+bEGvInA==", "dev": true, "dependencies": { "jest-diff": "^28.0.0", "jest-get-type": "^28.0.0" }, "engines": { - "node": "^14.15.0 || ^16.13.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "jest": ">=27.2.5" @@ -7963,49 +7246,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-leak-detector": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", @@ -8035,68 +7275,36 @@ } }, "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^28.1.3", "@types/node": "*" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -8158,49 +7366,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-resolve/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-resolve/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-runner": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", @@ -8233,123 +7398,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/jest-runner/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runner/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-runtime": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", @@ -8383,123 +7431,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/jest-runtime/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-snapshot": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", @@ -8534,53 +7465,7 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-snapshot/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-util": { + "node_modules/jest-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", @@ -8597,23 +7482,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-validate": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", @@ -8631,32 +7499,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-validate/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -8688,49 +7530,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-watcher/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", @@ -8760,32 +7559,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest/node_modules/@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -8828,6 +7601,52 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", + "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.5.0", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.1", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^10.0.0", + "ws": "^8.2.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsep": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.6.tgz", @@ -9275,9 +8094,9 @@ } }, "node_modules/markdownlint": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.1.tgz", - "integrity": "sha512-8sLz1ktz5s4E0IDum2H9aiWLQU7RA5Eket9HUW5IRwfFnW2RD2ZyqYePW+z71tMc7lrFZc1+yPmlN9lirbJnlg==", + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", "dev": true, "dependencies": { "markdown-it": "13.0.1" @@ -9287,9 +8106,9 @@ } }, "node_modules/markdownlint-cli": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.1.tgz", - "integrity": "sha512-hVLQ+72b5esQd7I+IqzBEB4x/4C+wJaxS2M6nqaGoDwrtNY6gydGf5CIUJtQcXtqsM615++a8TZPsvEtH6H4gw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.2.tgz", + "integrity": "sha512-xmJT1rGueUgT4yGNwk6D0oqQr90UJ7nMyakXtqjgswAkEhYYqjHew9RY8wDbOmh2R270IWjuKSeZzHDEGPAUkQ==", "dev": true, "dependencies": { "commander": "~9.4.0", @@ -9298,8 +8117,8 @@ "ignore": "~5.2.0", "js-yaml": "^4.1.0", "jsonc-parser": "~3.1.0", - "markdownlint": "~0.26.1", - "markdownlint-rule-helpers": "~0.17.1", + "markdownlint": "~0.26.2", + "markdownlint-rule-helpers": "~0.17.2", "minimatch": "~5.1.0", "run-con": "~1.2.11" }, @@ -9357,18 +8176,18 @@ } }, "node_modules/markdownlint-rule-helpers": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.1.tgz", - "integrity": "sha512-Djc5IjJt7VA5sZRisISsJC/rQXR7hr8JS9u6Q9/ce3mjPZdzw535cFGG0U6Mag+ldRTRmRwCcTfivOh57KUP4w==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", + "integrity": "sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/marked": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz", - "integrity": "sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw==", + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.19.tgz", + "integrity": "sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ==", "bin": { "marked": "bin/marked.js" }, @@ -9503,18 +8322,18 @@ } }, "node_modules/mermaid": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.3.tgz", - "integrity": "sha512-jTIYiqKwsUXVCoxHUVkK8t0QN3zSKIdJlb9thT0J5jCnzXyc+gqTbZE2QmjRfavFTPPn5eRy5zaFp7V+6RhxYg==", + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.6.tgz", + "integrity": "sha512-oBuQk7s55wQgEgH/AK0GYY8U0kBqOIGK9QlJL+VYxh+1kZQtU9tNwoy0gWCfBJDaFIRdfpc/fm9PagaIXg6XFQ==", "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.8", + "dompurify": "2.3.10", "graphlib": "^2.1.8", "khroma": "^2.0.0", - "moment-mini": "^2.24.0", + "moment-mini": "2.24.0", "stylis": "^4.0.10" } }, @@ -9633,9 +8452,9 @@ "integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==" }, "node_modules/monaco-editor": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", - "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==" + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.0.tgz", + "integrity": "sha512-VF+S5zG8wxfinLKLrWcl4WUizMx+LeJrG4PM/M78OhcwocpV0jiyhX/pG6Q9jIOhrb/ckYi6nHnaR5OojlOZCQ==" }, "node_modules/monaco-editor-webpack-plugin": { "version": "7.0.1", @@ -9751,6 +8570,28 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -9816,6 +8657,12 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nwsapi": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", + "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "dev": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9843,14 +8690,14 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -9975,6 +8822,29 @@ "node": ">= 8" } }, + "node_modules/pac-proxy-agent/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/pac-resolver": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", @@ -10001,12 +8871,6 @@ "node": ">=6" } }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -10044,6 +8908,12 @@ "node": ">= 0.10" } }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10175,6 +9045,18 @@ "node": ">=8" } }, + "node_modules/playwright-core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.1.tgz", + "integrity": "sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==", + "dev": true, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -10204,9 +9086,9 @@ } }, "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", "funding": [ { "type": "opencollective", @@ -10409,21 +9291,6 @@ "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", "dev": true }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "dependencies": { - "asap": "~2.0.6" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -10456,6 +9323,29 @@ "node": ">= 8" } }, + "node_modules/proxy-agent/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -10473,6 +9363,12 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -10481,20 +9377,11 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -10763,6 +9650,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/reserved": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", @@ -10855,9 +9748,9 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "node_modules/rollup": { - "version": "2.77.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz", - "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==", + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", "dev": true, "peer": true, "bin": { @@ -10943,6 +9836,18 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "optional": true }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -11228,9 +10133,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" }, "node_modules/spdx-ranges": { "version": "2.1.1", @@ -11420,22 +10325,20 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", + "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", "dev": true, "dependencies": { - "@csstools/selector-specificity": "^2.0.1", + "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", - "colord": "^2.9.2", + "colord": "^2.9.3", "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "execall": "^2.0.0", "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", + "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -11450,7 +10353,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.16", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -11464,7 +10367,7 @@ "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "bin": { "stylelint": "bin/stylelint.js" @@ -11478,24 +10381,24 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz", - "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", + "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", "dev": true, "peerDependencies": { - "stylelint": "^14.8.0" + "stylelint": "^14.10.0" } }, "node_modules/stylelint-config-standard": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz", - "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==", + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-28.0.0.tgz", + "integrity": "sha512-q/StuowDdDmFCravzGHAwgS9pjX0bdOQUEBBDIkIWsQuYGgYz/xsO8CM6eepmIQ1fc5bKdDVimlJZ6MoOUcJ5Q==", "dev": true, "dependencies": { - "stylelint-config-recommended": "^8.0.0" + "stylelint-config-recommended": "^9.0.0" }, "peerDependencies": { - "stylelint": "^14.9.0" + "stylelint": "^14.11.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -11504,18 +10407,6 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "node_modules/stylelint/node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -11608,32 +10499,15 @@ } }, "node_modules/swagger-ui-dist": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz", - "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A==" + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz", + "integrity": "sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw==" }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "dependencies": { - "get-port": "^3.1.0" - } + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true }, "node_modules/table": { "version": "6.8.0", @@ -11676,9 +10550,9 @@ } }, "node_modules/terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", + "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -11693,15 +10567,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", - "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz", + "integrity": "sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.14", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", - "terser": "^5.7.2" + "terser": "^5.14.1" }, "engines": { "node": ">= 10.13.0" @@ -11831,34 +10705,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, "node_modules/tippy.js": { "version": "6.3.7", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", @@ -11902,11 +10748,41 @@ "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.1.tgz", + "integrity": "sha512-Ns3k8QxkEzIfLZbRwLOrMPDqRa1BEAl4BzNNAOYY4BhBmEkf+HvP467F4NrD9loK3NcYflWOpUH3LJg0ehq/rQ==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } }, "node_modules/tributejs": { "version": "5.1.3", @@ -11993,12 +10869,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, "node_modules/typo-js": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz", @@ -12099,6 +10969,16 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", "dev": true }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12179,6 +11059,15 @@ "node": ">=6.0" } }, + "node_modules/vm2/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/vue": { "version": "2.6.14", "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", @@ -12336,6 +11225,27 @@ "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -12590,21 +11500,18 @@ } }, "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", + "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", "dev": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -12819,16 +11726,37 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xml-name-validator": { @@ -12840,6 +11768,12 @@ "node": ">=12" } }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -12901,9 +11835,9 @@ } }, "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" @@ -12949,27 +11883,27 @@ } }, "@babel/compat-data": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", - "integrity": "sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", + "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", "dev": true }, "@babel/core": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", - "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", + "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.10", + "@babel/generator": "^7.18.13", "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-module-transforms": "^7.18.9", "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.10", + "@babel/parser": "^7.18.13", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.10", - "@babel/types": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -12986,12 +11920,12 @@ } }, "@babel/generator": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz", - "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", + "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", "dev": true, "requires": { - "@babel/types": "^7.18.10", + "@babel/types": "^7.18.13", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -13202,9 +12136,9 @@ } }, "@babel/parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz", - "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -13344,19 +12278,19 @@ } }, "@babel/traverse": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz", - "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", + "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.10", + "@babel/generator": "^7.18.13", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.18.9", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -13370,9 +12304,9 @@ } }, "@babel/types": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", - "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", + "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.18.10", @@ -13410,9 +12344,9 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, "@esbuild/linux-loong64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", - "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", "optional": true }, "@eslint/eslintrc": { @@ -13452,20 +12386,6 @@ } } }, - "@happy-dom/jest-environment": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-6.0.4.tgz", - "integrity": "sha512-3FEWODVN4H7Hnkbm7IEtRE8lU7uitxSsnVagkQbfjjwKSUfF6BT9MJ95VF7nLimdc5ctOIa7ZbDietRRIpgSHw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "happy-dom": "^6.0.4", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, "@humanwhocodes/config-array": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", @@ -13584,62 +12504,6 @@ "jest-message-util": "^28.1.3", "jest-util": "^28.1.3", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "@jest/core": { @@ -13677,74 +12541,18 @@ "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^27.5.1" + "jest-mock": "^28.1.3" } }, "@jest/expect": { @@ -13767,17 +12575,17 @@ } }, "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/globals": { @@ -13789,107 +12597,6 @@ "@jest/environment": "^28.1.3", "@jest/expect": "^28.1.3", "@jest/types": "^28.1.3" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "@jest/reporters": { @@ -13923,62 +12630,6 @@ "strip-ansi": "^6.0.0", "terminal-link": "^2.0.0", "v8-to-istanbul": "^9.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "@jest/schemas": { @@ -14011,31 +12662,6 @@ "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - } } }, "@jest/test-sequencer": { @@ -14071,57 +12697,19 @@ "pirates": "^4.0.4", "slash": "^3.0.0", "write-file-atomic": "^4.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, @@ -14172,9 +12760,9 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -14230,15 +12818,25 @@ "fastq": "^1.6.0" } }, + "@playwright/test": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.1.tgz", + "integrity": "sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==", + "dev": true, + "requires": { + "@types/node": "*", + "playwright-core": "1.25.1" + } + }, "@popperjs/core": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", - "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@primer/octicons": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz", - "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==", + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.1.tgz", + "integrity": "sha512-DPlnpsARphzx9+kQexKsfLafOa+3FL3MKxaIPxz/isXiiZWgOuNTV8awHZ2Mm1M45mPqsBerucrFE8z2zVCbrg==", "requires": { "object-assign": "^4.1.1" } @@ -14278,9 +12876,9 @@ } }, "@sinclair/typebox": { - "version": "0.24.26", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz", - "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==", + "version": "0.24.28", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", + "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", "dev": true }, "@sinonjs/commons": { @@ -14293,18 +12891,18 @@ } }, "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } }, "@stoplight/better-ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.1.tgz", - "integrity": "sha512-rgxT+ZMeZbYRiOLNk6Oy6e/Ig1iQKo0IL8v/Y9E/0FewzgtkGs/p5dMeUpIFZXWj3RZaEPmfL9yh0oUEmNXZjg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", "dev": true, "requires": { "jsonpointer": "^5.0.0", @@ -14383,9 +12981,9 @@ "dev": true }, "@stoplight/spectral-cli": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz", - "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.1.tgz", + "integrity": "sha512-+qpwsDG2jQ4ULQmegBWonI3UnF6tUh351WDnV1GU8acl8eaeKbS+ZUNBgoP2f9tnMTfITdctVRFEGC3D6P7f9g==", "dev": true, "requires": { "@rollup/plugin-commonjs": "^20.0.0", @@ -14438,19 +13036,19 @@ } }, "@stoplight/spectral-core": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz", - "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.0.tgz", + "integrity": "sha512-CJOudlFTajdOS+A4QBkjogFQCVzoVcKQzJ1HMkLGq4RHgu9D5cy5iiMbADMW5e/Ffew+dxs3PPAH29Y0gaEHGg==", "dev": true, "requires": { - "@stoplight/better-ajv-errors": "1.0.1", - "@stoplight/json": "~3.18.1", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "~3.20.1", "@stoplight/lifecycle": "2.3.2", "@stoplight/path": "1.3.2", "@stoplight/spectral-parsers": "^1.0.0", "@stoplight/spectral-ref-resolver": "^1.0.0", "@stoplight/spectral-runtime": "^1.0.0", - "@stoplight/types": "~13.2.0", + "@stoplight/types": "~13.6.0", "@types/es-aggregate-error": "^1.0.2", "@types/json-schema": "^7.0.11", "ajv": "^8.6.0", @@ -14469,22 +13067,23 @@ }, "dependencies": { "@stoplight/json": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz", - "integrity": "sha512-QmELAqBS8DC+8YuG7+OvDVP6RaUVi8bzN0KKW2UEcZg+0a1sqeeZgfW079AmJIZg8HEN7udAt4iozIB8Dm0t1Q==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", "dev": true, "requires": { - "@stoplight/ordered-object-literal": "^1.0.2", - "@stoplight/types": "^13.0.0", + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", "jsonc-parser": "~2.2.1", "lodash": "^4.17.21", "safe-stable-stringify": "^1.1" } }, "@stoplight/types": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz", - "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==", + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -14506,17 +13105,16 @@ } }, "@stoplight/spectral-functions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz", - "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.1.tgz", + "integrity": "sha512-UWeUrxc1pu45ZNYKtK3OloMpkUNTPqwpmjbGUn4oEnbqrLEYu/B2oOg66EtGcadOBEsdOb7f5vaPlhUNNrpEpQ==", "dev": true, "requires": { - "@stoplight/better-ajv-errors": "1.0.1", - "@stoplight/json": "~3.17.1", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.1", "@stoplight/spectral-core": "^1.7.0", "@stoplight/spectral-formats": "^1.0.0", "@stoplight/spectral-runtime": "^1.1.0", - "@stoplight/types": "12.3.0", "ajv": "^8.6.3", "ajv-draft-04": "~1.0.0", "ajv-errors": "~3.0.0", @@ -14526,30 +13124,67 @@ }, "dependencies": { "@stoplight/json": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.17.2.tgz", - "integrity": "sha512-NwIVzanXRUy291J5BMkncCZRMG1Lx+aq+VidGQgfkJjgo8vh1Y/PSAz7fSU8gVGSZBCcqmOkMI7R4zw7DlfTwA==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", "dev": true, "requires": { - "@stoplight/ordered-object-literal": "^1.0.2", - "@stoplight/types": "^12.3.0", + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", "jsonc-parser": "~2.2.1", "lodash": "^4.17.21", "safe-stable-stringify": "^1.1" } + }, + "@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + } } } }, "@stoplight/spectral-parsers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.1.tgz", - "integrity": "sha512-JGKlrTxhjUzIGo2FOCf8Qp0WKTWXedoRNPovqYPE8pAp08epqU8DzHwl/i46BGH5yfTmouKMZgBN/PV2+Cr5jw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.2.tgz", + "integrity": "sha512-ZQXknJ+BM5Re4Opj4cgVlHgG2qyOk/wznKJq3Vf1qsBEg2CNzN0pJmSB0deRqW0kArqm44qpb8c+cz3F2rgMtw==", "dev": true, "requires": { - "@stoplight/json": "3.17.0", - "@stoplight/types": "12.3.0", - "@stoplight/yaml": "4.2.2", + "@stoplight/json": "~3.20.1", + "@stoplight/types": "^13.6.0", + "@stoplight/yaml": "~4.2.3", "tslib": "^2.3.1" + }, + "dependencies": { + "@stoplight/json": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.20.1.tgz", + "integrity": "sha512-FXfud+uWgIj1xv6nUO9WnmgmnVikaxJcbtR4XQt4C42n5c2qua3U05Z/3B57hP5TJRSj+tpn9ID6/bFeyYYlEg==", + "dev": true, + "requires": { + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", + "jsonc-parser": "~2.2.1", + "lodash": "^4.17.21", + "safe-stable-stringify": "^1.1" + } + }, + "@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + } + } } }, "@stoplight/spectral-ref-resolver": { @@ -14590,9 +13225,9 @@ }, "dependencies": { "@rollup/plugin-commonjs": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz", - "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz", + "integrity": "sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -14642,23 +13277,35 @@ "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.2.tgz", "integrity": "sha512-0ZMS/9sNU3kVo/6RF3eAv7MK9DY8WLjiVJB/tVyfF2lhr2R4kqh534jZ0PlrFB9CRXrdndzn1DbX6ihKZXft2w==", "dev": true + }, + "@stoplight/yaml": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.2.tgz", + "integrity": "sha512-N086FU8pmSpjc5TvMBjmlTniZVh3OXzmEh6SYljSLiuv6aMxgjyjf13YrAlUqgu0b4b6pQ5zmkjrfo9i0SiLsw==", + "dev": true, + "requires": { + "@stoplight/ordered-object-literal": "^1.0.1", + "@stoplight/types": "^12.0.0", + "@stoplight/yaml-ast-parser": "0.0.48", + "tslib": "^2.2.0" + } } } }, "@stoplight/spectral-rulesets": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz", - "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.12.0.tgz", + "integrity": "sha512-ktSO5YPzYzscnGTQffyKJwrzsR2i5cpPUC4yBp0isc6mOeiVec4r9sjMUN1mJt0RVnXi509vd0+YlMthFIZYnw==", "dev": true, "requires": { "@asyncapi/specs": "^2.14.0", - "@stoplight/better-ajv-errors": "1.0.1", + "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.1", "@stoplight/spectral-formats": "^1.2.0", "@stoplight/spectral-functions": "^1.5.1", "@stoplight/spectral-runtime": "^1.1.1", - "@stoplight/types": "^12.5.0", + "@stoplight/types": "^13.6.0", "@types/json-schema": "^7.0.7", "ajv": "^8.8.2", "ajv-formats": "~2.1.0", @@ -14668,9 +13315,9 @@ }, "dependencies": { "@stoplight/types": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", - "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -14705,15 +13352,27 @@ } }, "@stoplight/yaml": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.2.tgz", - "integrity": "sha512-N086FU8pmSpjc5TvMBjmlTniZVh3OXzmEh6SYljSLiuv6aMxgjyjf13YrAlUqgu0b4b6pQ5zmkjrfo9i0SiLsw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.3.tgz", + "integrity": "sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==", "dev": true, "requires": { "@stoplight/ordered-object-literal": "^1.0.1", - "@stoplight/types": "^12.0.0", + "@stoplight/types": "^13.0.0", "@stoplight/yaml-ast-parser": "0.0.48", "tslib": "^2.2.0" + }, + "dependencies": { + "@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + } + } } }, "@stoplight/yaml-ast-parser": { @@ -14728,9 +13387,9 @@ "integrity": "sha512-wpCQMhf5p5GhNg2MmGKXzUNwxe7zRiCsmqYsamez2beP7mKPCSiu+BjZcdN95yYSzO857kr0VfQewmGpS77nqA==" }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, "@trysound/sax": { @@ -14772,9 +13431,9 @@ } }, "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", + "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -14788,15 +13447,6 @@ "@types/tern": "*" } }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/es-aggregate-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz", @@ -14807,9 +13457,9 @@ } }, "@types/eslint": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", - "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", "requires": { "@types/estree": "*", "@types/json-schema": "*" @@ -14829,15 +13479,6 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -14871,6 +13512,17 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jsdom": { + "version": "16.2.15", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-16.2.15.tgz", + "integrity": "sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/parse5": "^6.0.3", + "@types/tough-cookie": "*" + } + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -14883,9 +13535,9 @@ "dev": true }, "@types/marked": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.3.tgz", - "integrity": "sha512-HnMWQkLJEf/PnxZIfbm0yGJRRZYYMhb++O9M36UCTA9z53uPvVoSlAwJr3XOpDEryb7Hwl1qAx/MV6YIW1RXxg==" + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.6.tgz", + "integrity": "sha512-ITAVUzsnVbhy5afxhs4PPPbrv2hKVEDH5BhhaQNQlVG0UNu+9A18XSdYr53nBdHZ0ADEQLl+ciOjXbs7eHdiQQ==" }, "@types/minimist": { "version": "1.2.2", @@ -14894,9 +13546,9 @@ "dev": true }, "@types/node": { - "version": "18.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", - "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -14910,16 +13562,16 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/prettier": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz", - "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", + "@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", "dev": true }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "@types/prettier": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", + "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, "@types/stack-utils": { @@ -14936,6 +13588,12 @@ "@types/estree": "*" } }, + "@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, "@types/urijs": { "version": "1.19.19", "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz", @@ -14943,9 +13601,9 @@ "dev": true }, "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", + "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -15164,6 +13822,12 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -15178,6 +13842,24 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, "acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", @@ -15192,9 +13874,9 @@ "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, "add-asset-webpack-plugin": { @@ -15350,12 +14032,6 @@ "printable-characters": "^1.0.42" } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, "ast-types": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", @@ -15497,6 +14173,12 @@ "fill-range": "^7.0.1" } }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, "browserslist": { "version": "4.21.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", @@ -15574,15 +14256,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001373", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz", - "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "version": "1.0.30001382", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz", + "integrity": "sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==" }, "chalk": { "version": "4.1.2", @@ -15678,15 +14354,6 @@ } } }, - "clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "requires": { - "is-regexp": "^2.0.0" - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -15694,9 +14361,9 @@ "dev": true }, "codemirror": { - "version": "5.65.7", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz", - "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A==" + "version": "5.65.8", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.8.tgz", + "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" }, "codemirror-spell-checker": { "version": "1.1.2", @@ -15726,9 +14393,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, "colorette": { @@ -15762,50 +14429,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "consolidate": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", @@ -15910,12 +14533,6 @@ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true }, - "css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true - }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -15930,6 +14547,29 @@ "css-tree": "^1.1.2" } }, + "cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, "d3": { "version": "7.6.1", "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz", @@ -16505,6 +15145,29 @@ "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", "dev": true }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } + } + }, "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", @@ -16543,6 +15206,12 @@ } } }, + "decimal.js": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", + "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "dev": true + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -16597,6 +15266,64 @@ "requires": { "tslib": "^2.0.1" } + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } } } }, @@ -16681,6 +15408,15 @@ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, "domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", @@ -16691,9 +15427,9 @@ } }, "dompurify": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz", - "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw==" + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", + "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" }, "domutils": { "version": "2.8.0", @@ -16721,21 +15457,21 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "easymde": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz", - "integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.17.0.tgz", + "integrity": "sha512-xerjhBh6G+FDfU2EBfKNEVqawYGqnK2zACKtyQlZKnxPoaesncRbHiSX5Yrf3Ur8KjEX1BvG7Ysccrd8hKTkig==", "requires": { "@types/codemirror": "^5.60.4", "@types/marked": "^4.0.1", "codemirror": "^5.63.1", "codemirror-spell-checker": "1.1.2", - "marked": "^4.0.10" + "marked": "^4.0.18" } }, "electron-to-chromium": { - "version": "1.4.210", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz", - "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==" + "version": "1.4.228", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.228.tgz", + "integrity": "sha512-XfDHCvou7CsDMlFwb0WZ1tWmW48e7Sn7VBRyPfZsZZila9esRsJl1trO+OqDNV97GggFSt0ISbWslKXfQkG//g==" }, "emittery": { "version": "0.10.2", @@ -16869,115 +15605,115 @@ } }, "esbuild": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz", - "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", "requires": { - "@esbuild/linux-loong64": "0.14.53", - "esbuild-android-64": "0.14.53", - "esbuild-android-arm64": "0.14.53", - "esbuild-darwin-64": "0.14.53", - "esbuild-darwin-arm64": "0.14.53", - "esbuild-freebsd-64": "0.14.53", - "esbuild-freebsd-arm64": "0.14.53", - "esbuild-linux-32": "0.14.53", - "esbuild-linux-64": "0.14.53", - "esbuild-linux-arm": "0.14.53", - "esbuild-linux-arm64": "0.14.53", - "esbuild-linux-mips64le": "0.14.53", - "esbuild-linux-ppc64le": "0.14.53", - "esbuild-linux-riscv64": "0.14.53", - "esbuild-linux-s390x": "0.14.53", - "esbuild-netbsd-64": "0.14.53", - "esbuild-openbsd-64": "0.14.53", - "esbuild-sunos-64": "0.14.53", - "esbuild-windows-32": "0.14.53", - "esbuild-windows-64": "0.14.53", - "esbuild-windows-arm64": "0.14.53" + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" } }, "esbuild-android-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", - "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", "optional": true }, "esbuild-android-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", - "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", "optional": true }, "esbuild-darwin-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", - "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", "optional": true }, "esbuild-darwin-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", - "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", "optional": true }, "esbuild-freebsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", - "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", "optional": true }, "esbuild-freebsd-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", - "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", "optional": true }, "esbuild-linux-32": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", - "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", "optional": true }, "esbuild-linux-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", - "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", "optional": true }, "esbuild-linux-arm": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", - "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", "optional": true }, "esbuild-linux-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", - "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", "optional": true }, "esbuild-linux-mips64le": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", - "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", "optional": true }, "esbuild-linux-ppc64le": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", - "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", "optional": true }, "esbuild-linux-riscv64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", - "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", "optional": true }, "esbuild-linux-s390x": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", - "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", "optional": true }, "esbuild-loader": { @@ -16994,39 +15730,39 @@ } }, "esbuild-netbsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", - "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", "optional": true }, "esbuild-openbsd-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", - "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", "optional": true }, "esbuild-sunos-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", - "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", "optional": true }, "esbuild-windows-32": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", - "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", "optional": true }, "esbuild-windows-64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", - "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", "optional": true }, "esbuild-windows-arm64": { - "version": "0.14.53", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", - "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", "optional": true }, "escalade": { @@ -17046,24 +15782,18 @@ "dev": true }, "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "requires": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "estraverse": "^5.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -17106,9 +15836,9 @@ } }, "eslint": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz", - "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", + "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.0", @@ -17194,13 +15924,12 @@ } }, "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -17211,55 +15940,6 @@ "requires": { "ms": "^2.1.1" } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true } } }, @@ -17318,9 +15998,9 @@ "requires": {} }, "eslint-plugin-sonarjs": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz", - "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.15.0.tgz", + "integrity": "sha512-LuxHdAe6VqSbi1phsUvNjbmXLuvlobmryQJJNyQYbdubCfz6K8tmgoqNiJPnz0pP2AbYDbtuPm0ajOMgMrC+dQ==", "dev": true, "requires": {} }, @@ -17347,9 +16027,9 @@ } }, "eslint-plugin-vue": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz", - "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.4.0.tgz", + "integrity": "sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -17473,15 +16153,6 @@ "strip-final-newline": "^2.0.0" } }, - "execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "requires": { - "clone-regexp": "^2.1.0" - } - }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -17499,62 +16170,6 @@ "jest-matcher-utils": "^28.1.3", "jest-message-util": "^28.1.3", "jest-util": "^28.1.3" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "fast-deep-equal": { @@ -17667,9 +16282,9 @@ } }, "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "font-awesome": { @@ -17678,13 +16293,13 @@ "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==" }, "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -17779,12 +16394,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true - }, "get-source": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", @@ -17837,6 +16446,14 @@ "file-uri-to-path": "2", "fs-extra": "^8.1.0", "ftp": "^0.3.10" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + } } }, "glob": { @@ -17961,24 +16578,9 @@ } }, "gsap": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.10.4.tgz", - "integrity": "sha512-6QatdkKxXCMfvCW4rM++0RqyLQAzFX5nwl3yHS0XPgkZBkiSEY3VZVbMltrdtsbER/xZonLtyHt684wRp4erlQ==" - }, - "happy-dom": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-6.0.4.tgz", - "integrity": "sha512-b+ID23Ms0BY08UNLymsOMG7EI2jSlwEt4cbJs938GZfeNAg+fqgkSO3TokQMgSOFoHznpjWmpVjBUL5boJ9PWw==", - "dev": true, - "requires": { - "css.escape": "^1.5.1", - "he": "^1.2.0", - "node-fetch": "^2.x.x", - "sync-request": "^6.1.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0" - } + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.0.tgz", + "integrity": "sha512-TV5aFGqXht+0o/CelnhCikSe3QGeG+q1XA/fyFFsMzesILHgWgFWIz0NuXIgcMaL5h7MG2l+j0BTupS5YyYkrw==" }, "hard-rejection": { "version": "2.1.0", @@ -18045,6 +16647,15 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -18057,18 +16668,6 @@ "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", "dev": true }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -18083,33 +16682,16 @@ } }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -18210,9 +16792,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", - "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", "dev": true }, "internal-slot": { @@ -18283,9 +16865,9 @@ "dev": true }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "requires": { "has": "^1.0.3" } @@ -18355,6 +16937,12 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -18374,12 +16962,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true - }, "is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", @@ -18512,31 +17094,6 @@ "@jest/types": "^28.1.3", "import-local": "^3.0.2", "jest-cli": "^28.1.3" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - } } }, "jest-changed-files": { @@ -18574,107 +17131,6 @@ "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-cli": { @@ -18695,45 +17151,6 @@ "jest-validate": "^28.1.3", "prompts": "^2.0.1", "yargs": "^17.3.1" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-config": { @@ -18764,45 +17181,6 @@ "pretty-format": "^28.1.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-diff": { @@ -18837,45 +17215,22 @@ "jest-get-type": "^28.0.2", "jest-util": "^28.1.3", "pretty-format": "^28.1.3" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } + } + }, + "jest-environment-jsdom": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-28.1.3.tgz", + "integrity": "sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/jsdom": "^16.2.4", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3", + "jsdom": "^19.0.0" } }, "jest-environment-node": { @@ -18890,113 +17245,12 @@ "@types/node": "*", "jest-mock": "^28.1.3", "jest-util": "^28.1.3" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-extended": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.1.tgz", - "integrity": "sha512-OSGbKUhbjy7QikfQyK3ishFrAqLeRodBzeJk7SuuWGACAT7HHcGuJ4aUQ3ueLANx4KSv1Pa7r1LJWGtJ3eI0xA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.0.2.tgz", + "integrity": "sha512-LnVZvwWLRV9AL8J7f4frKu0KHuTrbIFK15IqrvSwbFCYxalkuC5l7HfcofsksePrvlEJ2WAcfYNnu1+bEGvInA==", "dev": true, "requires": { "jest-diff": "^28.0.0", @@ -19027,45 +17281,6 @@ "jest-worker": "^28.1.3", "micromatch": "^4.0.4", "walker": "^1.0.8" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-leak-detector": { @@ -19091,54 +17306,29 @@ } }, "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } } }, "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "requires": { - "@jest/types": "^27.5.1", + "@jest/types": "^28.1.3", "@types/node": "*" } }, @@ -19170,45 +17360,6 @@ "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-resolve-dependencies": { @@ -19248,107 +17399,6 @@ "jest-worker": "^28.1.3", "p-limit": "^3.1.0", "source-map-support": "0.5.13" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-runtime": { @@ -19379,107 +17429,6 @@ "jest-util": "^28.1.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-snapshot": { @@ -19511,71 +17460,15 @@ "natural-compare": "^1.4.0", "pretty-format": "^28.1.3", "semver": "^7.3.5" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^27.5.1", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -19597,29 +17490,6 @@ "pretty-format": "^28.1.3" }, "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -19642,45 +17512,6 @@ "emittery": "^0.10.2", "jest-util": "^28.1.3", "string-length": "^4.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-worker": { @@ -19738,6 +17569,41 @@ "argparse": "^2.0.1" } }, + "jsdom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", + "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.5.0", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.1", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^10.0.0", + "ws": "^8.2.3", + "xml-name-validator": "^4.0.0" + } + }, "jsep": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.6.tgz", @@ -20091,18 +17957,18 @@ } }, "markdownlint": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.1.tgz", - "integrity": "sha512-8sLz1ktz5s4E0IDum2H9aiWLQU7RA5Eket9HUW5IRwfFnW2RD2ZyqYePW+z71tMc7lrFZc1+yPmlN9lirbJnlg==", + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", "dev": true, "requires": { "markdown-it": "13.0.1" } }, "markdownlint-cli": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.1.tgz", - "integrity": "sha512-hVLQ+72b5esQd7I+IqzBEB4x/4C+wJaxS2M6nqaGoDwrtNY6gydGf5CIUJtQcXtqsM615++a8TZPsvEtH6H4gw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.32.2.tgz", + "integrity": "sha512-xmJT1rGueUgT4yGNwk6D0oqQr90UJ7nMyakXtqjgswAkEhYYqjHew9RY8wDbOmh2R270IWjuKSeZzHDEGPAUkQ==", "dev": true, "requires": { "commander": "~9.4.0", @@ -20111,8 +17977,8 @@ "ignore": "~5.2.0", "js-yaml": "^4.1.0", "jsonc-parser": "~3.1.0", - "markdownlint": "~0.26.1", - "markdownlint-rule-helpers": "~0.17.1", + "markdownlint": "~0.26.2", + "markdownlint-rule-helpers": "~0.17.2", "minimatch": "~5.1.0", "run-con": "~1.2.11" }, @@ -20157,15 +18023,15 @@ } }, "markdownlint-rule-helpers": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.1.tgz", - "integrity": "sha512-Djc5IjJt7VA5sZRisISsJC/rQXR7hr8JS9u6Q9/ce3mjPZdzw535cFGG0U6Mag+ldRTRmRwCcTfivOh57KUP4w==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", + "integrity": "sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==", "dev": true }, "marked": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz", - "integrity": "sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw==" + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.19.tgz", + "integrity": "sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ==" }, "mathml-tag-names": { "version": "2.1.3", @@ -20268,18 +18134,18 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "mermaid": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.3.tgz", - "integrity": "sha512-jTIYiqKwsUXVCoxHUVkK8t0QN3zSKIdJlb9thT0J5jCnzXyc+gqTbZE2QmjRfavFTPPn5eRy5zaFp7V+6RhxYg==", + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.6.tgz", + "integrity": "sha512-oBuQk7s55wQgEgH/AK0GYY8U0kBqOIGK9QlJL+VYxh+1kZQtU9tNwoy0gWCfBJDaFIRdfpc/fm9PagaIXg6XFQ==", "requires": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.8", + "dompurify": "2.3.10", "graphlib": "^2.1.8", "khroma": "^2.0.0", - "moment-mini": "^2.24.0", + "moment-mini": "2.24.0", "stylis": "^4.0.10" } }, @@ -20361,9 +18227,9 @@ "integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==" }, "monaco-editor": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", - "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==" + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.0.tgz", + "integrity": "sha512-VF+S5zG8wxfinLKLrWcl4WUizMx+LeJrG4PM/M78OhcwocpV0jiyhX/pG6Q9jIOhrb/ckYi6nHnaR5OojlOZCQ==" }, "monaco-editor-webpack-plugin": { "version": "7.0.1", @@ -20444,6 +18310,30 @@ "dev": true, "requires": { "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } } }, "node-int64": { @@ -20501,6 +18391,12 @@ "boolbase": "^1.0.0" } }, + "nwsapi": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz", + "integrity": "sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -20519,14 +18415,14 @@ "dev": true }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, @@ -20610,6 +18506,25 @@ "pac-resolver": "^5.0.0", "raw-body": "^2.2.0", "socks-proxy-agent": "5" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + } } }, "pac-resolver": { @@ -20632,12 +18547,6 @@ "callsites": "^3.0.0" } }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -20660,6 +18569,12 @@ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -20751,6 +18666,12 @@ } } }, + "playwright-core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.1.tgz", + "integrity": "sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==", + "dev": true + }, "pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -20769,9 +18690,9 @@ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" }, "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -20896,21 +18817,6 @@ "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -20935,6 +18841,25 @@ "pac-proxy-agent": "^5.0.0", "proxy-from-env": "^1.0.0", "socks-proxy-agent": "^5.0.0" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + } } }, "proxy-from-env": { @@ -20954,19 +18879,22 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "queue-microtask": { "version": "1.2.3", @@ -21161,6 +19089,12 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "reserved": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", @@ -21224,9 +19158,9 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "rollup": { - "version": "2.77.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz", - "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==", + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", "dev": true, "peer": true, "requires": { @@ -21289,6 +19223,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "optional": true }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -21521,9 +19464,9 @@ } }, "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" }, "spdx-ranges": { "version": "2.1.1", @@ -21675,22 +19618,20 @@ "dev": true }, "stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", + "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", "dev": true, "requires": { - "@csstools/selector-specificity": "^2.0.1", + "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", - "colord": "^2.9.2", + "colord": "^2.9.3", "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "execall": "^2.0.0", "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", + "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -21705,7 +19646,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.16", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -21719,7 +19660,7 @@ "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "dependencies": { "balanced-match": { @@ -21728,12 +19669,6 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -21743,19 +19678,19 @@ } }, "stylelint-config-recommended": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz", - "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", + "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", "dev": true, "requires": {} }, "stylelint-config-standard": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz", - "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==", + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-28.0.0.tgz", + "integrity": "sha512-q/StuowDdDmFCravzGHAwgS9pjX0bdOQUEBBDIkIWsQuYGgYz/xsO8CM6eepmIQ1fc5bKdDVimlJZ6MoOUcJ5Q==", "dev": true, "requires": { - "stylelint-config-recommended": "^8.0.0" + "stylelint-config-recommended": "^9.0.0" } }, "stylis": { @@ -21822,29 +19757,15 @@ } }, "swagger-ui-dist": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz", - "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A==" + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz", + "integrity": "sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw==" }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "requires": { - "get-port": "^3.1.0" - } + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true }, "table": { "version": "6.8.0", @@ -21875,9 +19796,9 @@ } }, "terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", + "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", "requires": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -21902,15 +19823,15 @@ } }, "terser-webpack-plugin": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", - "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz", + "integrity": "sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==", "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.14", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", - "terser": "^5.7.2" + "terser": "^5.14.1" }, "dependencies": { "ajv": { @@ -21982,33 +19903,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - } - } - }, "tippy.js": { "version": "6.3.7", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", @@ -22043,11 +19937,34 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "tough-cookie": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.1.tgz", + "integrity": "sha512-Ns3k8QxkEzIfLZbRwLOrMPDqRa1BEAl4BzNNAOYY4BhBmEkf+HvP467F4NrD9loK3NcYflWOpUH3LJg0ehq/rQ==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + } + } + }, "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } }, "tributejs": { "version": "5.1.3", @@ -22115,12 +20032,6 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, "typo-js": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz", @@ -22190,6 +20101,16 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", "dev": true }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -22256,6 +20177,14 @@ "requires": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" + }, + "dependencies": { + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } } }, "vue": { @@ -22383,6 +20312,24 @@ "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -22556,21 +20503,13 @@ "dev": true }, "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", + "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", "dev": true, "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - } + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" } }, "which": { @@ -22726,21 +20665,34 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "requires": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" } }, + "ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "dev": true, + "requires": {} + }, "xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -22781,9 +20733,9 @@ }, "dependencies": { "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } diff --git a/package.json b/package.json index 42cba24f8..5a937ced9 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,11 @@ "dependencies": { "@claviska/jquery-minicolors": "2.3.6", "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", - "@primer/octicons": "17.4.0", + "@primer/octicons": "17.4.1", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", - "easymde": "2.16.1", + "easymde": "2.17.0", "esbuild-loader": "2.19.0", "escape-goat": "4.0.0", "fast-glob": "3.2.11", @@ -23,13 +23,13 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.3", + "mermaid": "9.1.6", "mini-css-extract-plugin": "2.6.1", - "monaco-editor": "0.33.0", + "monaco-editor": "0.34.0", "monaco-editor-webpack-plugin": "7.0.1", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.13.2", + "swagger-ui-dist": "4.14.0", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", @@ -46,20 +46,21 @@ "wrap-ansi": "8.0.1" }, "devDependencies": { - "@happy-dom/jest-environment": "6.0.4", - "@stoplight/spectral-cli": "6.5.0", - "eslint": "8.21.0", + "@playwright/test": "1.25.1", + "@stoplight/spectral-cli": "6.5.1", + "eslint": "8.22.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", - "eslint-plugin-sonarjs": "0.14.0", + "eslint-plugin-sonarjs": "0.15.0", "eslint-plugin-unicorn": "43.0.2", - "eslint-plugin-vue": "9.3.0", + "eslint-plugin-vue": "9.4.0", "jest": "28.1.3", - "jest-extended": "3.0.1", - "markdownlint-cli": "0.32.1", + "jest-environment-jsdom": "28.1.3", + "jest-extended": "3.0.2", + "markdownlint-cli": "0.32.2", "postcss-less": "6.0.0", - "stylelint": "14.9.1", - "stylelint-config-standard": "26.0.0", + "stylelint": "14.11.0", + "stylelint-config-standard": "28.0.0", "svgo": "2.8.0", "updates": "13.1.4" }, diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 000000000..af67717a2 --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,100 @@ +// @ts-check +import {devices} from '@playwright/test'; + +const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000'; + +/** + * @see https://playwright.dev/docs/test-configuration + * @type {import('@playwright/test').PlaywrightTestConfig} + */ +export default { + testDir: './tests/e2e/', + testMatch: /.*\.test\.e2e\.js/, // Match any .test.e2e.js files + + /* Maximum time one test can run for. */ + timeout: 30 * 1000, + + expect: { + + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 2000 + }, + + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: process.env.CI ? 'list' : [['list'], ['html', {outputFolder: 'tests/e2e/reports/', open: 'never'}]], + + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + headless: true, // set to false to debug + + locale: 'en-US', + + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 1000, + + /* Maximum time allowed for navigation, such as `page.goto()`. */ + navigationTimeout: 5 * 1000, + + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: BASE_URL, + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + + screenshot: 'only-on-failure', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + + /* Project-specific settings. */ + use: { + ...devices['Desktop Chrome'], + }, + }, + + { + name: 'firefox', + use: { + ...devices['Desktop Firefox'], + }, + }, + + { + name: 'webkit', + use: { + ...devices['Desktop Safari'], + }, + }, + + /* Test against mobile viewports. */ + { + name: 'Mobile Chrome', + use: { + ...devices['Pixel 5'], + }, + }, + { + name: 'Mobile Safari', + use: { + ...devices['iPhone 12'], + }, + }, + ], + + /* Folder for test artifacts such as screenshots, videos, traces, etc. */ + outputDir: 'tests/e2e/test-artifacts/', + /* Folder for test artifacts such as screenshots, videos, traces, etc. */ + snapshotDir: 'tests/e2e/test-snapshots/', +}; diff --git a/public/img/svg/gitea-join.svg b/public/img/svg/gitea-join.svg new file mode 100644 index 000000000..678b9374f --- /dev/null +++ b/public/img/svg/gitea-join.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/gitea-split.svg b/public/img/svg/gitea-split.svg new file mode 100644 index 000000000..f819255cc --- /dev/null +++ b/public/img/svg/gitea-split.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/gitea-vagrant.svg b/public/img/svg/gitea-vagrant.svg new file mode 100644 index 000000000..4c1b78cab --- /dev/null +++ b/public/img/svg/gitea-vagrant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/svg/gitea-whitespace.svg b/public/img/svg/gitea-whitespace.svg new file mode 100644 index 000000000..6b34f3373 --- /dev/null +++ b/public/img/svg/gitea-whitespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index cbf041a7e..93f9afca7 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -5,6 +5,7 @@ package packages import ( + gocontext "context" "net/http" "regexp" "strings" @@ -24,6 +25,7 @@ import ( "code.gitea.io/gitea/routers/api/packages/pub" "code.gitea.io/gitea/routers/api/packages/pypi" "code.gitea.io/gitea/routers/api/packages/rubygems" + "code.gitea.io/gitea/routers/api/packages/vagrant" "code.gitea.io/gitea/services/auth" context_service "code.gitea.io/gitea/services/context" ) @@ -38,10 +40,10 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) { } } -func Routes() *web.Route { +func Routes(ctx gocontext.Context) *web.Route { r := web.NewRoute() - r.Use(context.PackageContexter()) + r.Use(context.PackageContexter(ctx)) authMethods := []auth.Method{ &auth.OAuth2{}, @@ -265,15 +267,28 @@ func Routes() *web.Route { r.Delete("/yank", rubygems.DeletePackage) }, reqPackageAccess(perm.AccessModeWrite)) }) + r.Group("/vagrant", func() { + r.Group("/authenticate", func() { + r.Get("", vagrant.CheckAuthenticate) + }) + r.Group("/{name}", func() { + r.Head("", vagrant.CheckBoxAvailable) + r.Get("", vagrant.EnumeratePackageVersions) + r.Group("/{version}/{provider}", func() { + r.Get("", vagrant.DownloadPackageFile) + r.Put("", reqPackageAccess(perm.AccessModeWrite), vagrant.UploadPackageFile) + }) + }) + }) }, context_service.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) return r } -func ContainerRoutes() *web.Route { +func ContainerRoutes(ctx gocontext.Context) *web.Route { r := web.NewRoute() - r.Use(context.PackageContexter()) + r.Use(context.PackageContexter(ctx)) authMethods := []auth.Method{ &auth.Basic{}, diff --git a/routers/api/packages/composer/api.go b/routers/api/packages/composer/api.go index 45bb7eae1..ed52d1651 100644 --- a/routers/api/packages/composer/api.go +++ b/routers/api/packages/composer/api.go @@ -99,7 +99,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac Name: pd.Package.Name, Version: pd.Version.Version, Type: packageType, - Created: time.Unix(int64(pd.Version.CreatedUnix), 0), + Created: pd.Version.CreatedUnix.AsLocalTime(), Metadata: pd.Metadata.(*composer_module.Metadata), Dist: Dist{ Type: "zip", diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index 81cef39f1..86ef7cbd9 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -184,7 +184,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackage creates a new package diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index 04b0bb6cd..90924c7c4 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -475,7 +475,7 @@ func downloadFile(ctx *context.Context, fileFilter stringSet, fileKey string) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // DeleteRecipeV1 deletes the requested recipe(s) @@ -723,7 +723,7 @@ func listRevisions(ctx *context.Context, revisions []*conan_model.PropertyValue) revs := make([]*revisionInfo, 0, len(revisions)) for _, rev := range revisions { - revs = append(revs, &revisionInfo{Revision: rev.Value, Time: time.Unix(int64(rev.CreatedUnix), 0)}) + revs = append(revs, &revisionInfo{Revision: rev.Value, Time: rev.CreatedUnix.AsLocalTime()}) } jsonResponse(ctx, http.StatusOK, &RevisionList{revs}) @@ -743,7 +743,7 @@ func LatestRecipeRevision(ctx *context.Context) { return } - jsonResponse(ctx, http.StatusOK, &revisionInfo{Revision: revision.Value, Time: time.Unix(int64(revision.CreatedUnix), 0)}) + jsonResponse(ctx, http.StatusOK, &revisionInfo{Revision: revision.Value, Time: revision.CreatedUnix.AsLocalTime()}) } // LatestPackageRevision gets the latest package revision @@ -760,7 +760,7 @@ func LatestPackageRevision(ctx *context.Context) { return } - jsonResponse(ctx, http.StatusOK, &revisionInfo{Revision: revision.Value, Time: time.Unix(int64(revision.CreatedUnix), 0)}) + jsonResponse(ctx, http.StatusOK, &revisionInfo{Revision: revision.Value, Time: revision.CreatedUnix.AsLocalTime()}) } // ListRecipeRevisionFiles gets a list of all recipe revision files diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 79e5afb03..81891bec2 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -53,7 +53,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackage uploads the specific generic package. diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index f59cfc7c7..9c85e0874 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -138,7 +138,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackage creates a new package diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 072a15f95..bf00c199f 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -177,7 +177,7 @@ func servePackageFile(ctx *context.Context, params parameters) { } } - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go index 4b6b80397..763c59515 100644 --- a/routers/api/packages/npm/api.go +++ b/routers/api/packages/npm/api.go @@ -55,15 +55,18 @@ func createPackageMetadataVersion(registryURL string, pd *packages_model.Package metadata := pd.Metadata.(*npm_module.Metadata) return &npm_module.PackageMetadataVersion{ - ID: fmt.Sprintf("%s@%s", pd.Package.Name, pd.Version.Version), - Name: pd.Package.Name, - Version: pd.Version.Version, - Description: metadata.Description, - Author: npm_module.User{Name: metadata.Author}, - Homepage: metadata.ProjectURL, - License: metadata.License, - Dependencies: metadata.Dependencies, - Readme: metadata.Readme, + ID: fmt.Sprintf("%s@%s", pd.Package.Name, pd.Version.Version), + Name: pd.Package.Name, + Version: pd.Version.Version, + Description: metadata.Description, + Author: npm_module.User{Name: metadata.Author}, + Homepage: metadata.ProjectURL, + License: metadata.License, + Dependencies: metadata.Dependencies, + DevDependencies: metadata.DevelopmentDependencies, + PeerDependencies: metadata.PeerDependencies, + OptionalDependencies: metadata.OptionalDependencies, + Readme: metadata.Readme, Dist: npm_module.PackageDistribution{ Shasum: pd.Files[0].Blob.HashSHA1, Integrity: "sha512-" + base64.StdEncoding.EncodeToString(hashBytes), diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index d5ba70f96..66b999d47 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -103,7 +103,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackage creates a new package diff --git a/routers/api/packages/nuget/api.go b/routers/api/packages/nuget/api.go index b449cfc5b..964e05f92 100644 --- a/routers/api/packages/nuget/api.go +++ b/routers/api/packages/nuget/api.go @@ -176,7 +176,7 @@ func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDe return &RegistrationLeafResponse{ Type: []string{"Package", "http://schema.nuget.org/catalog#Permalink"}, Listed: true, - Published: time.Unix(int64(pd.Version.CreatedUnix), 0), + Published: pd.Version.CreatedUnix.AsLocalTime(), RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version), PackageContentURL: l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version), RegistrationIndexURL: l.GetRegistrationIndexURL(pd.Package.Name), diff --git a/routers/api/packages/nuget/auth.go b/routers/api/packages/nuget/auth.go index 26a5b9018..1dad45264 100644 --- a/routers/api/packages/nuget/auth.go +++ b/routers/api/packages/nuget/auth.go @@ -7,7 +7,7 @@ package nuget import ( "net/http" - "code.gitea.io/gitea/models" + auth_model "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" @@ -22,9 +22,9 @@ func (a *Auth) Name() string { // https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { - token, err := models.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey")) + token, err := auth_model.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey")) if err != nil { - if !(models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err)) { + if !(auth_model.IsErrAccessTokenNotExist(err) || auth_model.IsErrAccessTokenEmpty(err)) { log.Error("GetAccessTokenBySHA: %v", err) } return nil @@ -37,7 +37,7 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS } token.UpdatedUnix = timeutil.TimeStampNow() - if err := models.UpdateAccessToken(token); err != nil { + if err := auth_model.UpdateAccessToken(token); err != nil { log.Error("UpdateAccessToken: %v", err) } diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 81ea28bca..eadf7486a 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -179,7 +179,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackage creates a new package with the metadata contained in the uploaded nupgk file @@ -378,7 +378,7 @@ func DownloadSymbolFile(ctx *context.Context) { return } - s, _, err := packages_service.GetPackageFileStream(ctx, pfs[0]) + s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { apiError(ctx, http.StatusNotFound, err) @@ -389,7 +389,7 @@ func DownloadSymbolFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pfs[0].Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // DeletePackage hard deletes the package diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index 470f44623..9af0ceeb0 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -69,7 +69,7 @@ func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescr return &versionMetadata{ Version: pd.Version.Version, ArchiveURL: fmt.Sprintf("%s/files/%s.tar.gz", baseURL, url.PathEscape(pd.Version.Version)), - Published: time.Unix(int64(pd.Version.CreatedUnix), 0), + Published: pd.Version.CreatedUnix.AsLocalTime(), Pubspec: pd.Metadata.(*pub_module.Metadata).Pubspec, } } @@ -271,5 +271,5 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 9209c4edd..07cf766c6 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -16,7 +16,6 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" pypi_module "code.gitea.io/gitea/modules/packages/pypi" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" @@ -58,7 +57,6 @@ func PackageMetadata(ctx *context.Context) { ctx.Data["RegistryURL"] = setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/pypi" ctx.Data["PackageDescriptor"] = pds[0] ctx.Data["PackageDescriptors"] = pds - ctx.Render = templates.HTMLRenderer() ctx.HTML(http.StatusOK, "api/packages/pypi/simple") } @@ -90,7 +88,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 4f066a830..319c94b91 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -188,7 +188,7 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go new file mode 100644 index 000000000..7750e5dc4 --- /dev/null +++ b/routers/api/packages/vagrant/vagrant.go @@ -0,0 +1,239 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package vagrant + +import ( + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strings" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + packages_module "code.gitea.io/gitea/modules/packages" + vagrant_module "code.gitea.io/gitea/modules/packages/vagrant" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/routers/api/packages/helper" + packages_service "code.gitea.io/gitea/services/packages" + + "github.com/hashicorp/go-version" +) + +func apiError(ctx *context.Context, status int, obj interface{}) { + helper.LogAndProcessError(ctx, status, obj, func(message string) { + ctx.JSON(status, struct { + Errors []string `json:"errors"` + }{ + Errors: []string{ + message, + }, + }) + }) +} + +func CheckAuthenticate(ctx *context.Context) { + if ctx.Doer == nil { + apiError(ctx, http.StatusUnauthorized, "Invalid access token") + return + } + + ctx.Status(http.StatusOK) +} + +func CheckBoxAvailable(ctx *context.Context) { + pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name")) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + if len(pvs) == 0 { + apiError(ctx, http.StatusNotFound, err) + return + } + + ctx.JSON(http.StatusOK, nil) // needs to be Content-Type: application/json +} + +type packageMetadata struct { + Name string `json:"name"` + Description string `json:"description,omitempty"` + ShortDescription string `json:"short_description,omitempty"` + Versions []*versionMetadata `json:"versions"` +} + +type versionMetadata struct { + Version string `json:"version"` + Status string `json:"status"` + DescriptionHTML string `json:"description_html,omitempty"` + DescriptionMarkdown string `json:"description_markdown,omitempty"` + Providers []*providerData `json:"providers"` +} + +type providerData struct { + Name string `json:"name"` + URL string `json:"url"` + Checksum string `json:"checksum"` + ChecksumType string `json:"checksum_type"` +} + +func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescriptor) *versionMetadata { + versionURL := baseURL + "/" + url.PathEscape(pd.Version.Version) + + providers := make([]*providerData, 0, len(pd.Files)) + + for _, f := range pd.Files { + providers = append(providers, &providerData{ + Name: f.Properties.GetByName(vagrant_module.PropertyProvider), + URL: versionURL + "/" + url.PathEscape(f.File.Name), + Checksum: f.Blob.HashSHA512, + ChecksumType: "sha512", + }) + } + + return &versionMetadata{ + Status: "active", + Version: pd.Version.Version, + Providers: providers, + } +} + +func EnumeratePackageVersions(ctx *context.Context) { + pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name")) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + if len(pvs) == 0 { + apiError(ctx, http.StatusNotFound, err) + return + } + + pds, err := packages_model.GetPackageDescriptors(ctx, pvs) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + sort.Slice(pds, func(i, j int) bool { + return pds[i].SemVer.LessThan(pds[j].SemVer) + }) + + baseURL := fmt.Sprintf("%sapi/packages/%s/vagrant/%s", setting.AppURL, url.PathEscape(ctx.Package.Owner.Name), url.PathEscape(pds[0].Package.Name)) + + versions := make([]*versionMetadata, 0, len(pds)) + for _, pd := range pds { + versions = append(versions, packageDescriptorToMetadata(baseURL, pd)) + } + + ctx.JSON(http.StatusOK, &packageMetadata{ + Name: pds[0].Package.Name, + Description: pds[len(pds)-1].Metadata.(*vagrant_module.Metadata).Description, + Versions: versions, + }) +} + +func UploadPackageFile(ctx *context.Context) { + boxName := ctx.Params("name") + boxVersion := ctx.Params("version") + _, err := version.NewSemver(boxVersion) + if err != nil { + apiError(ctx, http.StatusBadRequest, err) + return + } + boxProvider := ctx.Params("provider") + if !strings.HasSuffix(boxProvider, ".box") { + apiError(ctx, http.StatusBadRequest, err) + return + } + + upload, needsClose, err := ctx.UploadStream() + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + if needsClose { + defer upload.Close() + } + + buf, err := packages_module.CreateHashedBufferFromReader(upload, 32*1024*1024) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + defer buf.Close() + + metadata, err := vagrant_module.ParseMetadataFromBox(buf) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + _, _, err = packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeVagrant, + Name: boxName, + Version: boxVersion, + }, + SemverCompatible: true, + Creator: ctx.Doer, + Metadata: metadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: strings.ToLower(boxProvider), + }, + Data: buf, + IsLead: true, + Properties: map[string]string{ + vagrant_module.PropertyProvider: strings.TrimSuffix(boxProvider, ".box"), + }, + }, + ) + if err != nil { + if err == packages_model.ErrDuplicatePackageFile { + apiError(ctx, http.StatusConflict, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + + ctx.Status(http.StatusCreated) +} + +func DownloadPackageFile(ctx *context.Context) { + s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + ctx, + &packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeVagrant, + Name: ctx.Params("name"), + Version: ctx.Params("version"), + }, + &packages_service.PackageFileInfo{ + Filename: ctx.Params("provider"), + }, + ) + if err != nil { + if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { + apiError(ctx, http.StatusNotFound, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + defer s.Close() + + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) +} diff --git a/routers/api/v1/admin/adopt.go b/routers/api/v1/admin/adopt.go index 8f11ab67f..48222f89e 100644 --- a/routers/api/v1/admin/adopt.go +++ b/routers/api/v1/admin/adopt.go @@ -7,10 +7,10 @@ package admin import ( "net/http" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" repo_service "code.gitea.io/gitea/services/repository" @@ -110,7 +110,7 @@ func AdoptRepository(ctx *context.APIContext) { ctx.NotFound() return } - if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{ + if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ Name: repoName, IsPrivate: true, }); err != nil { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 40423d913..069532ef4 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -7,64 +7,65 @@ // // This documentation describes the Gitea API. // -// Schemes: http, https -// BasePath: /api/v1 -// Version: {{AppVer | JSEscape | Safe}} -// License: MIT http://opensource.org/licenses/MIT +// Schemes: http, https +// BasePath: /api/v1 +// Version: {{AppVer | JSEscape | Safe}} +// License: MIT http://opensource.org/licenses/MIT // -// Consumes: -// - application/json -// - text/plain +// Consumes: +// - application/json +// - text/plain // -// Produces: -// - application/json -// - text/html +// Produces: +// - application/json +// - text/html // -// Security: -// - BasicAuth : -// - Token : -// - AccessToken : -// - AuthorizationHeaderToken : -// - SudoParam : -// - SudoHeader : -// - TOTPHeader : +// Security: +// - BasicAuth : +// - Token : +// - AccessToken : +// - AuthorizationHeaderToken : +// - SudoParam : +// - SudoHeader : +// - TOTPHeader : // -// SecurityDefinitions: -// BasicAuth: -// type: basic -// Token: -// type: apiKey -// name: token -// in: query -// AccessToken: -// type: apiKey -// name: access_token -// in: query -// AuthorizationHeaderToken: -// type: apiKey -// name: Authorization -// in: header -// description: API tokens must be prepended with "token" followed by a space. -// SudoParam: -// type: apiKey -// name: sudo -// in: query -// description: Sudo API request as the user provided as the key. Admin privileges are required. -// SudoHeader: -// type: apiKey -// name: Sudo -// in: header -// description: Sudo API request as the user provided as the key. Admin privileges are required. -// TOTPHeader: -// type: apiKey -// name: X-GITEA-OTP -// in: header -// description: Must be used in combination with BasicAuth if two-factor authentication is enabled. +// SecurityDefinitions: +// BasicAuth: +// type: basic +// Token: +// type: apiKey +// name: token +// in: query +// AccessToken: +// type: apiKey +// name: access_token +// in: query +// AuthorizationHeaderToken: +// type: apiKey +// name: Authorization +// in: header +// description: API tokens must be prepended with "token" followed by a space. +// SudoParam: +// type: apiKey +// name: sudo +// in: query +// description: Sudo API request as the user provided as the key. Admin privileges are required. +// SudoHeader: +// type: apiKey +// name: Sudo +// in: header +// description: Sudo API request as the user provided as the key. Admin privileges are required. +// TOTPHeader: +// type: apiKey +// name: X-GITEA-OTP +// in: header +// description: Must be used in combination with BasicAuth if two-factor authentication is enabled. // // swagger:meta package v1 import ( + gocontext "context" "fmt" "net/http" "reflect" @@ -605,7 +606,7 @@ func buildAuthGroup() *auth.Group { } // Routes registers all v1 APIs routes to web application. -func Routes() *web.Route { +func Routes(ctx gocontext.Context) *web.Route { m := web.NewRoute() m.Use(securityHeaders()) @@ -623,7 +624,7 @@ func Routes() *web.Route { m.Use(context.APIContexter()) group := buildAuthGroup() - if err := group.Init(); err != nil { + if err := group.Init(ctx); err != nil { log.Error("Could not initialize '%s' auth method, error: %s", group.Name(), err) } diff --git a/routers/api/v1/misc/markdown_test.go b/routers/api/v1/misc/markdown_test.go index 9beb88be1..7809fa5cc 100644 --- a/routers/api/v1/misc/markdown_test.go +++ b/routers/api/v1/misc/markdown_test.go @@ -29,7 +29,7 @@ const ( ) func createContext(req *http.Request) (*context.Context, *httptest.ResponseRecorder) { - rnd := templates.HTMLRenderer() + _, rnd := templates.HTMLRenderer(req.Context()) resp := httptest.NewRecorder() c := &context.Context{ Req: req, diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go index 44cb4ae76..9948f90a1 100644 --- a/routers/api/v1/notify/notifications.go +++ b/routers/api/v1/notify/notifications.go @@ -8,7 +8,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" @@ -22,16 +22,16 @@ func NewAvailable(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/NotificationCount" - ctx.JSON(http.StatusOK, api.NotificationCount{New: models.CountUnread(ctx, ctx.Doer.ID)}) + ctx.JSON(http.StatusOK, api.NotificationCount{New: activities_model.CountUnread(ctx, ctx.Doer.ID)}) } -func getFindNotificationOptions(ctx *context.APIContext) *models.FindNotificationOptions { +func getFindNotificationOptions(ctx *context.APIContext) *activities_model.FindNotificationOptions { before, since, err := context.GetQueryBeforeSince(ctx.Context) if err != nil { ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) return nil } - opts := &models.FindNotificationOptions{ + opts := &activities_model.FindNotificationOptions{ ListOptions: utils.GetListOptions(ctx), UserID: ctx.Doer.ID, UpdatedBeforeUnix: before, @@ -50,17 +50,17 @@ func getFindNotificationOptions(ctx *context.APIContext) *models.FindNotificatio return opts } -func subjectToSource(value []string) (result []models.NotificationSource) { +func subjectToSource(value []string) (result []activities_model.NotificationSource) { for _, v := range value { switch strings.ToLower(v) { case "issue": - result = append(result, models.NotificationSourceIssue) + result = append(result, activities_model.NotificationSourceIssue) case "pull": - result = append(result, models.NotificationSourcePullRequest) + result = append(result, activities_model.NotificationSourcePullRequest) case "commit": - result = append(result, models.NotificationSourceCommit) + result = append(result, activities_model.NotificationSourceCommit) case "repository": - result = append(result, models.NotificationSourceRepository) + result = append(result, activities_model.NotificationSourceRepository) } } return result diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 4e9dd806d..f8e1fb086 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -9,31 +9,31 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" ) -func statusStringToNotificationStatus(status string) models.NotificationStatus { +func statusStringToNotificationStatus(status string) activities_model.NotificationStatus { switch strings.ToLower(strings.TrimSpace(status)) { case "unread": - return models.NotificationStatusUnread + return activities_model.NotificationStatusUnread case "read": - return models.NotificationStatusRead + return activities_model.NotificationStatusRead case "pinned": - return models.NotificationStatusPinned + return activities_model.NotificationStatusPinned default: return 0 } } -func statusStringsToNotificationStatuses(statuses, defaultStatuses []string) []models.NotificationStatus { +func statusStringsToNotificationStatuses(statuses, defaultStatuses []string) []activities_model.NotificationStatus { if len(statuses) == 0 { statuses = defaultStatuses } - results := make([]models.NotificationStatus, 0, len(statuses)) + results := make([]activities_model.NotificationStatus, 0, len(statuses)) for _, status := range statuses { notificationStatus := statusStringToNotificationStatus(status) if notificationStatus > 0 { @@ -109,13 +109,13 @@ func ListRepoNotifications(ctx *context.APIContext) { } opts.RepoID = ctx.Repo.Repository.ID - totalCount, err := models.CountNotifications(opts) + totalCount, err := activities_model.CountNotifications(opts) if err != nil { ctx.InternalServerError(err) return } - nl, err := models.GetNotifications(ctx, opts) + nl, err := activities_model.GetNotifications(ctx, opts) if err != nil { ctx.InternalServerError(err) return @@ -192,7 +192,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { } } - opts := &models.FindNotificationOptions{ + opts := &activities_model.FindNotificationOptions{ UserID: ctx.Doer.ID, RepoID: ctx.Repo.Repository.ID, UpdatedBeforeUnix: lastRead, @@ -203,7 +203,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) log.Error("%v", opts.Status) } - nl, err := models.GetNotifications(ctx, opts) + nl, err := activities_model.GetNotifications(ctx, opts) if err != nil { ctx.InternalServerError(err) return @@ -211,13 +211,13 @@ func ReadRepoNotifications(ctx *context.APIContext) { targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) if targetStatus == 0 { - targetStatus = models.NotificationStatusRead + targetStatus = activities_model.NotificationStatusRead } changed := make([]*structs.NotificationThread, 0, len(nl)) for _, n := range nl { - notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) + notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 7d8d34504..44a1d30a5 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" @@ -86,10 +86,10 @@ func ReadThread(ctx *context.APIContext) { targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) if targetStatus == 0 { - targetStatus = models.NotificationStatusRead + targetStatus = activities_model.NotificationStatusRead } - notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) + notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) if err != nil { ctx.InternalServerError(err) return @@ -101,8 +101,8 @@ func ReadThread(ctx *context.APIContext) { ctx.JSON(http.StatusResetContent, convert.ToNotificationThread(notif)) } -func getThread(ctx *context.APIContext) *models.Notification { - n, err := models.GetNotificationByID(ctx.ParamsInt64(":id")) +func getThread(ctx *context.APIContext) *activities_model.Notification { + n, err := activities_model.GetNotificationByID(ctx.ParamsInt64(":id")) if err != nil { if db.IsErrNotExist(err) { ctx.Error(http.StatusNotFound, "GetNotificationByID", err) diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index b92330778..1b6706e16 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/structs" @@ -69,13 +69,13 @@ func ListNotifications(ctx *context.APIContext) { return } - totalCount, err := models.CountNotifications(opts) + totalCount, err := activities_model.CountNotifications(opts) if err != nil { ctx.InternalServerError(err) return } - nl, err := models.GetNotifications(ctx, opts) + nl, err := activities_model.GetNotifications(ctx, opts) if err != nil { ctx.InternalServerError(err) return @@ -140,7 +140,7 @@ func ReadNotifications(ctx *context.APIContext) { lastRead = tmpLastRead.Unix() } } - opts := &models.FindNotificationOptions{ + opts := &activities_model.FindNotificationOptions{ UserID: ctx.Doer.ID, UpdatedBeforeUnix: lastRead, } @@ -148,7 +148,7 @@ func ReadNotifications(ctx *context.APIContext) { statuses := ctx.FormStrings("status-types") opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) } - nl, err := models.GetNotifications(ctx, opts) + nl, err := activities_model.GetNotifications(ctx, opts) if err != nil { ctx.InternalServerError(err) return @@ -156,13 +156,13 @@ func ReadNotifications(ctx *context.APIContext) { targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) if targetStatus == 0 { - targetStatus = models.NotificationStatusRead + targetStatus = activities_model.NotificationStatusRead } changed := make([]*structs.NotificationThread, 0, len(nl)) for _, n := range nl { - notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) + notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index db37bac57..c891d0e12 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + org_service "code.gitea.io/gitea/services/org" ) // ListTeams list all the teams of an organization @@ -656,8 +657,8 @@ func AddTeamRepository(ctx *context.APIContext) { ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") return } - if err := models.AddRepository(ctx.Org.Team, repo); err != nil { - ctx.Error(http.StatusInternalServerError, "AddRepository", err) + if err := org_service.TeamAddRepository(ctx.Org.Team, repo); err != nil { + ctx.Error(http.StatusInternalServerError, "TeamAddRepository", err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 2c0238910..29fa6c85a 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -41,7 +41,7 @@ func ListPackages(ctx *context.APIContext) { // in: query // description: package type filter // type: string - // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pub, pypi, rubygems] + // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pub, pypi, rubygems, vagrant] // - name: q // in: query // description: name filter diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index aa425e582..0e6236216 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -16,6 +16,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + repo_module "code.gitea.io/gitea/modules/repository" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" @@ -174,7 +175,7 @@ func AddCollaborator(ctx *context.APIContext) { return } - if err := models.AddCollaborator(ctx.Repo.Repository, collaborator); err != nil { + if err := repo_module.AddCollaborator(ctx.Repo.Repository, collaborator); err != nil { ctx.Error(http.StatusInternalServerError, "AddCollaborator", err) return } diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index b196ce977..12c329c20 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -17,7 +17,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/routers/api/v1/utils" ) @@ -53,7 +52,7 @@ func GetSingleCommit(ctx *context.APIContext) { // "$ref": "#/responses/notFound" sha := ctx.Params(":sha") - if (validation.GitRefNamePatternInvalid.MatchString(sha) || !validation.CheckGitRefAdditionalRulesValid(sha)) && !git.SHAPattern.MatchString(sha) { + if !git.IsValidRefPattern(sha) { ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha)) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 8353a4e50..6dead81e6 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -8,6 +8,7 @@ package repo import ( "bytes" "encoding/base64" + "errors" "fmt" "io" "net/http" @@ -28,7 +29,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" - "code.gitea.io/gitea/routers/web/repo" + archiver_service "code.gitea.io/gitea/services/repository/archiver" files_service "code.gitea.io/gitea/services/repository/files" ) @@ -294,7 +295,53 @@ func GetArchive(ctx *context.APIContext) { defer gitRepo.Close() } - repo.Download(ctx.Context) + archiveDownload(ctx) +} + +func archiveDownload(ctx *context.APIContext) { + uri := ctx.Params("*") + aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri) + if err != nil { + if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { + ctx.Error(http.StatusBadRequest, "unknown archive format", err) + } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) { + ctx.Error(http.StatusNotFound, "unrecognized reference", err) + } else { + ctx.ServerError("archiver_service.NewRequest", err) + } + return + } + + archiver, err := aReq.Await(ctx) + if err != nil { + ctx.ServerError("archiver.Await", err) + return + } + + download(ctx, aReq.GetArchiveName(), archiver) +} + +func download(ctx *context.APIContext, archiveName string, archiver *repo_model.RepoArchiver) { + downloadName := ctx.Repo.Repository.Name + "-" + archiveName + + rPath := archiver.RelativePath() + if setting.RepoArchive.ServeDirect { + // If we have a signed url (S3, object storage), redirect to this directly. + u, err := storage.RepoArchives.URL(rPath, downloadName) + if u != nil && err == nil { + ctx.Redirect(u.String()) + return + } + } + + // If we have matched and access to release or issue + fr, err := storage.RepoArchives.Open(rPath) + if err != nil { + ctx.ServerError("Open", err) + return + } + defer fr.Close() + ctx.ServeContent(downloadName, fr, archiver.CreatedUnix.AsLocalTime()) } // GetEditorconfig get editor config of a repository diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go index 29b126db9..47f46df33 100644 --- a/routers/api/v1/repo/git_ref.go +++ b/routers/api/v1/repo/git_ref.go @@ -34,7 +34,7 @@ func GetGitAllRefs(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/responses/Reference" + // # "$ref": "#/responses/Reference" TODO: swagger doesnt support different output formats by ref // "$ref": "#/responses/ReferenceList" // "404": // "$ref": "#/responses/notFound" @@ -67,7 +67,7 @@ func GetGitRefs(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/responses/Reference" + // # "$ref": "#/responses/Reference" TODO: swagger doesnt support different output formats by ref // "$ref": "#/responses/ReferenceList" // "404": // "$ref": "#/responses/notFound" diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 8a546e581..b17142c0f 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" @@ -140,7 +141,7 @@ func TestHook(ctx *context.APIContext) { // required: true // - name: ref // in: query - // description: "The name of the commit/branch/tag. Default the repositoryโ€™s default branch (usually master)" + // description: "The name of the commit/branch/tag, indicates which commit will be loaded to the webhook payload." // type: string // required: false // responses: @@ -153,6 +154,11 @@ func TestHook(ctx *context.APIContext) { return } + ref := git.BranchPrefix + ctx.Repo.Repository.DefaultBranch + if r := ctx.FormTrim("ref"); r != "" { + ref = r + } + hookID := ctx.ParamsInt64(":id") hook, err := utils.GetRepoHook(ctx, ctx.Repo.Repository.ID, hookID) if err != nil { @@ -161,10 +167,12 @@ func TestHook(ctx *context.APIContext) { commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit) + commitID := ctx.Repo.Commit.ID.String() if err := webhook_service.PrepareWebhook(hook, ctx.Repo.Repository, webhook.HookEventPush, &api.PushPayload{ - Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, - Before: ctx.Repo.Commit.ID.String(), - After: ctx.Repo.Commit.ID.String(), + Ref: ref, + Before: commitID, + After: commitID, + CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID), Commits: []*api.PayloadCommit{commit}, HeadCommit: commit, Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone), diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index b9a6c5af6..1e26403ec 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -566,6 +566,8 @@ func ListMyTrackedTimes(ctx *context.APIContext) { // swagger:operation GET /user/times user userCurrentTrackedTimes // --- // summary: List the current user's tracked times + // produces: + // - application/json // parameters: // - name: page // in: query @@ -575,9 +577,6 @@ func ListMyTrackedTimes(ctx *context.APIContext) { // in: query // description: page size of results // type: integer - // produces: - // - application/json - // parameters: // - name: since // in: query // description: Only show times updated after the given time. This is a timestamp in RFC 3339 format diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index f868c5395..ed371d787 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -170,7 +170,7 @@ func Migrate(ctx *context.APIContext) { opts.Releases = false } - repo, err := repo_module.CreateRepository(ctx.Doer, repoOwner, models.CreateRepoOptions{ + repo, err := repo_module.CreateRepository(ctx.Doer, repoOwner, repo_module.CreateRepoOptions{ Name: opts.RepoName, Description: opts.Description, OriginalURL: form.CloneAddr, diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index bd8e27e40..67f097a42 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/validation" ) // GetNote Get a note corresponding to a single commit from a repository @@ -47,7 +46,7 @@ func GetNote(ctx *context.APIContext) { // "$ref": "#/responses/notFound" sha := ctx.Params(":sha") - if (validation.GitRefNamePatternInvalid.MatchString(sha) || !validation.CheckGitRefAdditionalRulesValid(sha)) && !git.SHAPattern.MatchString(sha) { + if !git.IsValidRefPattern(sha) { ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha)) return } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 50d2c9484..dda05203d 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -14,6 +14,7 @@ import ( "time" "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" @@ -753,7 +754,7 @@ func MergePullRequest(ctx *context.APIContext) { if ctx.IsSigned { // Update issue-user. - if err = models.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { + if err = activities_model.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { ctx.Error(http.StatusInternalServerError, "ReadBy", err) return } diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 80009f78e..acc9696e1 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/perm" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -49,12 +50,12 @@ func GetRelease(ctx *context.APIContext) { // "$ref": "#/responses/notFound" id := ctx.ParamsInt64(":id") - release, err := models.GetReleaseByID(ctx, id) - if err != nil && !models.IsErrReleaseNotExist(err) { + release, err := repo_model.GetReleaseByID(ctx, id) + if err != nil && !repo_model.IsErrReleaseNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } - if err != nil && models.IsErrReleaseNotExist(err) || + if err != nil && repo_model.IsErrReleaseNotExist(err) || release.IsTag || release.RepoID != ctx.Repo.Repository.ID { ctx.NotFound() return @@ -114,7 +115,7 @@ func ListReleases(ctx *context.APIContext) { listOptions.PageSize = ctx.FormInt("per_page") } - opts := models.FindReleasesOptions{ + opts := repo_model.FindReleasesOptions{ ListOptions: listOptions, IncludeDrafts: ctx.Repo.AccessMode >= perm.AccessModeWrite || ctx.Repo.UnitAccessMode(unit.TypeReleases) >= perm.AccessModeWrite, IncludeTags: false, @@ -122,7 +123,7 @@ func ListReleases(ctx *context.APIContext) { IsPreRelease: ctx.FormOptionalBool("pre-release"), } - releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) + releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) return @@ -136,7 +137,7 @@ func ListReleases(ctx *context.APIContext) { rels[i] = convert.ToRelease(release) } - filteredCount, err := models.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts) + filteredCount, err := repo_model.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts) if err != nil { ctx.InternalServerError(err) return @@ -179,9 +180,9 @@ func CreateRelease(ctx *context.APIContext) { // "409": // "$ref": "#/responses/error" form := web.GetForm(ctx).(*api.CreateReleaseOption) - rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName) + rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, form.TagName) if err != nil { - if !models.IsErrReleaseNotExist(err) { + if !repo_model.IsErrReleaseNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetRelease", err) return } @@ -189,7 +190,7 @@ func CreateRelease(ctx *context.APIContext) { if len(form.Target) == 0 { form.Target = ctx.Repo.Repository.DefaultBranch } - rel = &models.Release{ + rel = &repo_model.Release{ RepoID: ctx.Repo.Repository.ID, PublisherID: ctx.Doer.ID, Publisher: ctx.Doer, @@ -203,7 +204,7 @@ func CreateRelease(ctx *context.APIContext) { Repo: ctx.Repo.Repository, } if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil { - if models.IsErrReleaseAlreadyExist(err) { + if repo_model.IsErrReleaseAlreadyExist(err) { ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) } else { ctx.Error(http.StatusInternalServerError, "CreateRelease", err) @@ -272,12 +273,12 @@ func EditRelease(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.EditReleaseOption) id := ctx.ParamsInt64(":id") - rel, err := models.GetReleaseByID(ctx, id) - if err != nil && !models.IsErrReleaseNotExist(err) { + rel, err := repo_model.GetReleaseByID(ctx, id) + if err != nil && !repo_model.IsErrReleaseNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } - if err != nil && models.IsErrReleaseNotExist(err) || + if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { ctx.NotFound() return @@ -307,7 +308,7 @@ func EditRelease(ctx *context.APIContext) { } // reload data from database - rel, err = models.GetReleaseByID(ctx, id) + rel, err = repo_model.GetReleaseByID(ctx, id) if err != nil { ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return @@ -350,12 +351,12 @@ func DeleteRelease(ctx *context.APIContext) { // "$ref": "#/responses/empty" id := ctx.ParamsInt64(":id") - rel, err := models.GetReleaseByID(ctx, id) - if err != nil && !models.IsErrReleaseNotExist(err) { + rel, err := repo_model.GetReleaseByID(ctx, id) + if err != nil && !repo_model.IsErrReleaseNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } - if err != nil && models.IsErrReleaseNotExist(err) || + if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { ctx.NotFound() return diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 8694653c0..a469877c1 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -7,7 +7,6 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -57,6 +56,10 @@ func GetReleaseAttachment(ctx *context.APIContext) { attachID := ctx.ParamsInt64(":asset") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { + if repo_model.IsErrAttachmentNotExist(err) { + ctx.NotFound() + return + } ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } @@ -98,8 +101,12 @@ func ListReleaseAttachments(ctx *context.APIContext) { // "$ref": "#/responses/AttachmentList" releaseID := ctx.ParamsInt64(":id") - release, err := models.GetReleaseByID(ctx, releaseID) + release, err := repo_model.GetReleaseByID(ctx, releaseID) if err != nil { + if repo_model.IsErrReleaseNotExist(err) { + ctx.NotFound() + return + } ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } @@ -164,8 +171,12 @@ func CreateReleaseAttachment(ctx *context.APIContext) { // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") - release, err := models.GetReleaseByID(ctx, releaseID) + release, err := repo_model.GetReleaseByID(ctx, releaseID) if err != nil { + if repo_model.IsErrReleaseNotExist(err) { + ctx.NotFound() + return + } ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } @@ -244,6 +255,10 @@ func EditReleaseAttachment(ctx *context.APIContext) { attachID := ctx.ParamsInt64(":asset") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { + if repo_model.IsErrAttachmentNotExist(err) { + ctx.NotFound() + return + } ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } @@ -302,6 +317,10 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { attachID := ctx.ParamsInt64(":asset") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { + if repo_model.IsErrAttachmentNotExist(err) { + ctx.NotFound() + return + } ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 73dee73e1..2cb97c58a 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" releaseservice "code.gitea.io/gitea/services/release" @@ -44,9 +45,9 @@ func GetReleaseByTag(ctx *context.APIContext) { tag := ctx.Params(":tag") - release, err := models.GetRelease(ctx.Repo.Repository.ID, tag) + release, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tag) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound() return } @@ -97,9 +98,9 @@ func DeleteReleaseByTag(ctx *context.APIContext) { tag := ctx.Params(":tag") - release, err := models.GetRelease(ctx.Repo.Repository.ID, tag) + release, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tag) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound() return } diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index cdd1f7d5c..6f40bb3e4 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" @@ -232,7 +231,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre if opt.AutoInit && opt.Readme == "" { opt.Readme = "Default" } - repo, err := repo_service.CreateRepository(ctx.Doer, owner, models.CreateRepoOptions{ + repo, err := repo_service.CreateRepository(ctx.Doer, owner, repo_module.CreateRepoOptions{ Name: opt.Name, Description: opt.Description, IssueLabels: opt.IssueLabels, @@ -585,7 +584,6 @@ func Edit(ctx *context.APIContext) { // description: name of the repo to edit // type: string // required: true - // required: true // - name: body // in: body // description: "Properties of a repo that you can edit" diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 433d823c7..f0f850399 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -10,6 +10,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -249,9 +250,9 @@ func DeleteTag(ctx *context.APIContext) { // "$ref": "#/responses/conflict" tagName := ctx.Params("*") - tag, err := models.GetRelease(ctx.Repo.Repository.ID, tagName) + tag, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound() return } diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index 47c69d722..f485f2086 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" + org_service "code.gitea.io/gitea/services/org" ) // ListTeams list a repository's teams @@ -199,7 +200,7 @@ func changeRepoTeam(ctx *context.APIContext, add bool) { ctx.Error(http.StatusUnprocessableEntity, "alreadyAdded", fmt.Errorf("team '%s' is already added to repo", team.Name)) return } - err = models.AddRepository(team, ctx.Repo.Repository) + err = org_service.TeamAddRepository(team, ctx.Repo.Repository) } else { if !repoHasTeam { ctx.Error(http.StatusUnprocessableEntity, "notAdded", fmt.Errorf("team '%s' was not added to repo", team.Name)) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index d423bddbb..6d9564854 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -10,10 +10,11 @@ import ( "net/http" "net/url" - "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -72,9 +73,9 @@ func NewWikiPage(ctx *context.APIContext) { form.ContentBase64 = string(content) if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil { - if models.IsErrWikiReservedName(err) { + if repo_model.IsErrWikiReservedName(err) { ctx.Error(http.StatusBadRequest, "IsErrWikiReservedName", err) - } else if models.IsErrWikiAlreadyExist(err) { + } else if repo_model.IsErrWikiAlreadyExist(err) { ctx.Error(http.StatusBadRequest, "IsErrWikiAlreadyExists", err) } else { ctx.Error(http.StatusInternalServerError, "AddWikiPage", err) @@ -85,6 +86,7 @@ func NewWikiPage(ctx *context.APIContext) { wikiPage := getWikiPage(ctx, wikiName) if !ctx.Written() { + notification.NotifyNewWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName, form.Message) ctx.JSON(http.StatusCreated, wikiPage) } } @@ -152,6 +154,7 @@ func EditWikiPage(ctx *context.APIContext) { wikiPage := getWikiPage(ctx, newWikiName) if !ctx.Written() { + notification.NotifyEditWikiPage(ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message) ctx.JSON(http.StatusOK, wikiPage) } } @@ -242,6 +245,8 @@ func DeleteWikiPage(ctx *context.APIContext) { return } + notification.NotifyDeleteWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName) + ctx.Status(http.StatusNoContent) } @@ -314,7 +319,7 @@ func ListWikiPages(ctx *context.APIContext) { } wikiName, err := wiki_service.FilenameToName(entry.Name()) if err != nil { - if models.IsErrWikiInvalidFileName(err) { + if repo_model.IsErrWikiInvalidFileName(err) { continue } ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) diff --git a/routers/api/v1/swagger/user.go b/routers/api/v1/swagger/user.go index a4d520123..857bdc2a1 100644 --- a/routers/api/v1/swagger/user.go +++ b/routers/api/v1/swagger/user.go @@ -5,7 +5,7 @@ package swagger import ( - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" api "code.gitea.io/gitea/modules/structs" ) @@ -40,7 +40,7 @@ type swaggerModelEditUserOption struct { // swagger:response UserHeatmapData type swaggerResponseUserHeatmapData struct { // in:body - Body []models.UserHeatmapData `json:"body"` + Body []activities_model.UserHeatmapData `json:"body"` } // UserSettings diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 0d2e8401c..a94db7923 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -11,8 +11,7 @@ import ( "net/http" "strconv" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/auth" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -45,14 +44,14 @@ func ListAccessTokens(ctx *context.APIContext) { // "200": // "$ref": "#/responses/AccessTokenList" - opts := models.ListAccessTokensOptions{UserID: ctx.Doer.ID, ListOptions: utils.GetListOptions(ctx)} + opts := auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID, ListOptions: utils.GetListOptions(ctx)} - count, err := models.CountAccessTokens(opts) + count, err := auth_model.CountAccessTokens(opts) if err != nil { ctx.InternalServerError(err) return } - tokens, err := models.ListAccessTokens(opts) + tokens, err := auth_model.ListAccessTokens(opts) if err != nil { ctx.InternalServerError(err) return @@ -98,12 +97,12 @@ func CreateAccessToken(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateAccessTokenOption) - t := &models.AccessToken{ + t := &auth_model.AccessToken{ UID: ctx.Doer.ID, Name: form.Name, } - exist, err := models.AccessTokenByNameExists(t) + exist, err := auth_model.AccessTokenByNameExists(t) if err != nil { ctx.InternalServerError(err) return @@ -113,7 +112,7 @@ func CreateAccessToken(ctx *context.APIContext) { return } - if err := models.NewAccessToken(t); err != nil { + if err := auth_model.NewAccessToken(t); err != nil { ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) return } @@ -155,7 +154,7 @@ func DeleteAccessToken(ctx *context.APIContext) { tokenID, _ := strconv.ParseInt(token, 0, 64) if tokenID == 0 { - tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{ + tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{ Name: token, UserID: ctx.Doer.ID, }) @@ -180,8 +179,8 @@ func DeleteAccessToken(ctx *context.APIContext) { return } - if err := models.DeleteAccessTokenByID(tokenID, ctx.Doer.ID); err != nil { - if models.IsErrAccessTokenNotExist(err) { + if err := auth_model.DeleteAccessTokenByID(tokenID, ctx.Doer.ID); err != nil { + if auth_model.IsErrAccessTokenNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "DeleteAccessTokenByID", err) @@ -213,7 +212,7 @@ func CreateOauth2Application(ctx *context.APIContext) { data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) - app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ + app, err := auth_model.CreateOAuth2Application(ctx, auth_model.CreateOAuth2ApplicationOptions{ Name: data.Name, UserID: ctx.Doer.ID, RedirectURIs: data.RedirectURIs, @@ -252,7 +251,7 @@ func ListOauth2Applications(ctx *context.APIContext) { // "200": // "$ref": "#/responses/OAuth2ApplicationList" - apps, total, err := auth.ListOAuth2Applications(ctx.Doer.ID, utils.GetListOptions(ctx)) + apps, total, err := auth_model.ListOAuth2Applications(ctx.Doer.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) return @@ -288,8 +287,8 @@ func DeleteOauth2Application(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" appID := ctx.ParamsInt64(":id") - if err := auth.DeleteOAuth2Application(appID, ctx.Doer.ID); err != nil { - if auth.IsErrOAuthApplicationNotFound(err) { + if err := auth_model.DeleteOAuth2Application(appID, ctx.Doer.ID); err != nil { + if auth_model.IsErrOAuthApplicationNotFound(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err) @@ -320,9 +319,9 @@ func GetOauth2Application(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" appID := ctx.ParamsInt64(":id") - app, err := auth.GetOAuth2ApplicationByID(ctx, appID) + app, err := auth_model.GetOAuth2ApplicationByID(ctx, appID) if err != nil { - if auth.IsErrOauthClientIDInvalid(err) || auth.IsErrOAuthApplicationNotFound(err) { + if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetOauth2ApplicationByID", err) @@ -363,14 +362,14 @@ func UpdateOauth2Application(ctx *context.APIContext) { data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) - app, err := auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ + app, err := auth_model.UpdateOAuth2Application(auth_model.UpdateOAuth2ApplicationOptions{ Name: data.Name, UserID: ctx.Doer.ID, ID: appID, RedirectURIs: data.RedirectURIs, }) if err != nil { - if auth.IsErrOauthClientIDInvalid(err) || auth.IsErrOAuthApplicationNotFound(err) { + if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "UpdateOauth2ApplicationByID", err) diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 170ffb773..31c13172f 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -48,11 +48,6 @@ func AddEmail(ctx *context.APIContext) { // produces: // - application/json // parameters: - // - name: options - // in: body - // schema: - // "$ref": "#/definitions/CreateEmailOption" - // parameters: // - name: body // in: body // schema: diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index b211a24a0..b87cf0041 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -7,6 +7,7 @@ package user import ( "fmt" "net/http" + "strings" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" @@ -177,6 +178,12 @@ func VerifyUserGPGKey(ctx *context.APIContext) { token := asymkey_model.VerificationToken(ctx.Doer, 1) lastToken := asymkey_model.VerificationToken(ctx.Doer, 0) + form.KeyID = strings.TrimLeft(form.KeyID, "0") + if form.KeyID == "" { + ctx.NotFound() + return + } + _, err := asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, token, form.Signature) if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { _, err = asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, lastToken, form.Signature) diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index 2a3cb15c0..69197aef2 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -8,7 +8,7 @@ package user import ( "net/http" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -139,7 +139,7 @@ func GetUserHeatmapData(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - heatmap, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) + heatmap, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err) return diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index ba008f587..7e4dfca9a 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -126,6 +126,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID PullRequestComment: pullHook(form.Events, string(webhook.HookEventPullRequestComment)), PullRequestReview: pullHook(form.Events, "pull_request_review"), PullRequestSync: pullHook(form.Events, string(webhook.HookEventPullRequestSync)), + Wiki: util.IsStringInSlice(string(webhook.HookEventWiki), form.Events, true), Repository: util.IsStringInSlice(string(webhook.HookEventRepository), form.Events, true), Release: util.IsStringInSlice(string(webhook.HookEventRelease), form.Events, true), }, @@ -249,6 +250,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh w.Delete = util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true) w.Fork = util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true) w.Repository = util.IsStringInSlice(string(webhook.HookEventRepository), form.Events, true) + w.Wiki = util.IsStringInSlice(string(webhook.HookEventWiki), form.Events, true) w.Release = util.IsStringInSlice(string(webhook.HookEventRelease), form.Events, true) w.BranchFilter = form.BranchFilter diff --git a/routers/init.go b/routers/init.go index 612fc5a83..85a38899e 100644 --- a/routers/init.go +++ b/routers/init.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/ssh" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/svg" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -110,12 +111,12 @@ func GlobalInitInstalled(ctx context.Context) { log.Info("Run Mode: %s", util.ToTitleCase(setting.RunMode)) // Setup i18n - translation.InitLocales() + translation.InitLocales(ctx) setting.NewServices() mustInit(storage.Init) - mailer.NewContext() + mailer.NewContext(ctx) mustInit(cache.NewContext) notification.NewContext() mustInit(archiver.Init) @@ -163,18 +164,19 @@ func GlobalInitInstalled(ctx context.Context) { } // NormalRoutes represents non install routes -func NormalRoutes() *web.Route { +func NormalRoutes(ctx context.Context) *web.Route { + ctx, _ = templates.HTMLRenderer(ctx) r := web.NewRoute() for _, middle := range common.Middlewares() { r.Use(middle) } - r.Mount("/", web_routers.Routes()) - r.Mount("/api/v1", apiv1.Routes()) + r.Mount("/", web_routers.Routes(ctx)) + r.Mount("/api/v1", apiv1.Routes(ctx)) r.Mount("/api/internal", private.Routes()) if setting.Packages.Enabled { - r.Mount("/api/packages", packages_router.Routes()) - r.Mount("/v2", packages_router.ContainerRoutes()) + r.Mount("/api/packages", packages_router.Routes(ctx)) + r.Mount("/v2", packages_router.ContainerRoutes(ctx)) } return r } diff --git a/routers/install/install.go b/routers/install/install.go index 8060414a1..890725b9a 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -6,6 +6,7 @@ package install import ( + goctx "context" "fmt" "net/http" "os" @@ -51,39 +52,41 @@ func getSupportedDbTypeNames() (dbTypeNames []map[string]string) { } // Init prepare for rendering installation page -func Init(next http.Handler) http.Handler { - rnd := templates.HTMLRenderer() +func Init(ctx goctx.Context) func(next http.Handler) http.Handler { + _, rnd := templates.HTMLRenderer(ctx) dbTypeNames := getSupportedDbTypeNames() - return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - if setting.InstallLock { - resp.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") - _ = rnd.HTML(resp, http.StatusOK, string(tplPostInstall), nil) - return - } - locale := middleware.Locale(resp, req) - startTime := time.Now() - ctx := context.Context{ - Resp: context.NewResponse(resp), - Flash: &middleware.Flash{}, - Locale: locale, - Render: rnd, - Session: session.GetSession(req), - Data: map[string]interface{}{ - "locale": locale, - "Title": locale.Tr("install.install"), - "PageIsInstall": true, - "DbTypeNames": dbTypeNames, - "AllLangs": translation.AllLangs(), - "PageStartTime": startTime, + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if setting.InstallLock { + resp.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") + _ = rnd.HTML(resp, http.StatusOK, string(tplPostInstall), nil) + return + } + locale := middleware.Locale(resp, req) + startTime := time.Now() + ctx := context.Context{ + Resp: context.NewResponse(resp), + Flash: &middleware.Flash{}, + Locale: locale, + Render: rnd, + Session: session.GetSession(req), + Data: map[string]interface{}{ + "locale": locale, + "Title": locale.Tr("install.install"), + "PageIsInstall": true, + "DbTypeNames": dbTypeNames, + "AllLangs": translation.AllLangs(), + "PageStartTime": startTime, - "PasswordHashAlgorithms": user_model.AvailableHashAlgorithms, - }, - } - defer ctx.Close() + "PasswordHashAlgorithms": user_model.AvailableHashAlgorithms, + }, + } + defer ctx.Close() - ctx.Req = context.WithContext(req, &ctx) - next.ServeHTTP(resp, ctx.Req) - }) + ctx.Req = context.WithContext(req, &ctx) + next.ServeHTTP(resp, ctx.Req) + }) + } } // Install render installation page diff --git a/routers/install/routes.go b/routers/install/routes.go index fdabcb9dc..761747782 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -5,6 +5,7 @@ package install import ( + goctx "context" "fmt" "net/http" "path" @@ -29,8 +30,8 @@ func (d *dataStore) GetData() map[string]interface{} { return *d } -func installRecovery() func(next http.Handler) http.Handler { - rnd := templates.HTMLRenderer() +func installRecovery(ctx goctx.Context) func(next http.Handler) http.Handler { + _, rnd := templates.HTMLRenderer(ctx) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { defer func() { @@ -82,7 +83,7 @@ func installRecovery() func(next http.Handler) http.Handler { } // Routes registers the install routes -func Routes() *web.Route { +func Routes(ctx goctx.Context) *web.Route { r := web.NewRoute() for _, middle := range common.Middlewares() { r.Use(middle) @@ -105,8 +106,8 @@ func Routes() *web.Route { Domain: setting.SessionConfig.Domain, })) - r.Use(installRecovery()) - r.Use(Init) + r.Use(installRecovery(ctx)) + r.Use(Init(ctx)) r.Get("/", Install) r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall) r.Get("/api/healthz", healthcheck.Check) diff --git a/routers/install/routes_test.go b/routers/install/routes_test.go index 29003c384..e69d2d15d 100644 --- a/routers/install/routes_test.go +++ b/routers/install/routes_test.go @@ -5,13 +5,16 @@ package install import ( + "context" "testing" "github.com/stretchr/testify/assert" ) func TestRoutes(t *testing.T) { - routes := Routes() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + routes := Routes(ctx) assert.NotNil(t, routes) assert.EqualValues(t, "/", routes.R.Routes()[0].Pattern) assert.Nil(t, routes.R.Routes()[0].SubRoutes) diff --git a/routers/install/setting.go b/routers/install/setting.go index cf0a01ce3..c4912f112 100644 --- a/routers/install/setting.go +++ b/routers/install/setting.go @@ -24,7 +24,7 @@ func PreloadSettings(ctx context.Context) bool { log.Info("Log path: %s", setting.LogRootPath) log.Info("Configuration file: %s", setting.CustomConf) log.Info("Prepare to run install page") - translation.InitLocales() + translation.InitLocales(ctx) if setting.EnableSQLite3 { log.Info("SQLite3 is supported") } diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go index c773034c5..17471ef8a 100644 --- a/routers/web/admin/admin.go +++ b/routers/web/admin/admin.go @@ -15,7 +15,7 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -128,7 +128,7 @@ func Dashboard(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true - ctx.Data["Stats"] = models.GetStatistic() + ctx.Data["Stats"] = activities_model.GetStatistic() ctx.Data["NeedUpdate"] = updatechecker.GetNeedUpdate() ctx.Data["RemoteVersion"] = updatechecker.GetRemoteVersion() // FIXME: update periodically @@ -144,7 +144,7 @@ func DashboardPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.dashboard") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminDashboard"] = true - ctx.Data["Stats"] = models.GetStatistic() + ctx.Data["Stats"] = activities_model.GetStatistic() updateSystemStatus() ctx.Data["SysStatus"] = sysStatus diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go index 8ce981ec2..17b00975e 100644 --- a/routers/web/admin/repos.go +++ b/routers/web/admin/repos.go @@ -9,13 +9,13 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/explore" @@ -148,7 +148,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) { if has || !isDir { // Fallthrough to failure mode } else if action == "adopt" { - if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{ + if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ Name: dirSplit[1], IsPrivate: true, }); err != nil { diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index aab633ec8..5cdfb8142 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -209,7 +209,11 @@ func NewUserPost(ctx *context.Context) { func prepareUserInfo(ctx *context.Context) *user_model.User { u, err := user_model.GetUserByID(ctx.ParamsInt64(":userid")) if err != nil { - ctx.ServerError("GetUserByID", err) + if user_model.IsErrUserNotExist(err) { + ctx.Redirect(setting.AppSubURL + "/admin/users") + } else { + ctx.ServerError("GetUserByID", err) + } return nil } ctx.Data["User"] = u diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 714ae96fa..b400fdac8 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -15,8 +15,8 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/auth" + org_model "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -296,7 +296,7 @@ func InfoOAuth(ctx *context.Context) { // returns a list of "org" and "org:team" strings, // that the given user is a part of. func getOAuthGroupsForUser(user *user_model.User) ([]string, error) { - orgs, err := models.GetUserOrgsList(user) + orgs, err := org_model.GetUserOrgsList(user) if err != nil { return nil, fmt.Errorf("GetUserOrgList: %v", err) } diff --git a/routers/web/base.go b/routers/web/base.go index 30a24a127..2441d6d51 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -5,6 +5,7 @@ package web import ( + goctx "context" "errors" "fmt" "io" @@ -123,8 +124,8 @@ func (d *dataStore) GetData() map[string]interface{} { // Recovery returns a middleware that recovers from any panics and writes a 500 and a log if so. // This error will be created with the gitea 500 page. -func Recovery() func(next http.Handler) http.Handler { - rnd := templates.HTMLRenderer() +func Recovery(ctx goctx.Context) func(next http.Handler) http.Handler { + _, rnd := templates.HTMLRenderer(ctx) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { defer func() { diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index b5485f583..8cb615b7b 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -48,10 +48,11 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { } var ( - repos []*repo_model.Repository - count int64 - err error - orderBy db.SearchOrderBy + repos []*repo_model.Repository + count int64 + err error + orderBy db.SearchOrderBy + onlyShowRelevant bool ) ctx.Data["SortType"] = ctx.FormString("sort") @@ -60,8 +61,6 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { orderBy = db.SearchOrderByNewest case "oldest": orderBy = db.SearchOrderByOldest - case "recentupdate": - orderBy = db.SearchOrderByRecentUpdated case "leastupdate": orderBy = db.SearchOrderByLeastUpdated case "reversealphabetically": @@ -83,9 +82,16 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { default: ctx.Data["SortType"] = "recentupdate" orderBy = db.SearchOrderByRecentUpdated + onlyShowRelevant = setting.UI.OnlyShowRelevantRepos && !ctx.FormBool("no_filter") } keyword := ctx.FormTrim("q") + if keyword != "" { + onlyShowRelevant = false + } + + ctx.Data["OnlyShowRelevant"] = onlyShowRelevant + topicOnly := ctx.FormBool("topic") ctx.Data["TopicOnly"] = topicOnly @@ -107,6 +113,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { TopicOnly: topicOnly, Language: language, IncludeDescription: setting.UI.SearchRepoDescription, + OnlyShowRelevant: onlyShowRelevant, }) if err != nil { ctx.ServerError("SearchRepository", err) @@ -133,6 +140,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { pager.SetDefaultParams(ctx) pager.AddParam(ctx, "topic", "TopicOnly") pager.AddParam(ctx, "language", "Language") + pager.AddParamString("no_filter", ctx.FormString("no_filter")) ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, opts.TplName) diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go index 978469d12..e16c54b8d 100644 --- a/routers/web/feed/convert.go +++ b/routers/web/feed/convert.go @@ -12,7 +12,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" @@ -23,33 +23,33 @@ import ( "github.com/gorilla/feeds" ) -func toBranchLink(act *models.Action) string { +func toBranchLink(act *activities_model.Action) string { return act.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(act.GetBranch()) } -func toTagLink(act *models.Action) string { +func toTagLink(act *activities_model.Action) string { return act.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(act.GetTag()) } -func toIssueLink(act *models.Action) string { +func toIssueLink(act *activities_model.Action) string { return act.GetRepoLink() + "/issues/" + url.PathEscape(act.GetIssueInfos()[0]) } -func toPullLink(act *models.Action) string { +func toPullLink(act *activities_model.Action) string { return act.GetRepoLink() + "/pulls/" + url.PathEscape(act.GetIssueInfos()[0]) } -func toSrcLink(act *models.Action) string { +func toSrcLink(act *activities_model.Action) string { return act.GetRepoLink() + "/src/" + util.PathEscapeSegments(act.GetBranch()) } -func toReleaseLink(act *models.Action) string { +func toReleaseLink(act *activities_model.Action) string { return act.GetRepoLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch()) } // renderMarkdown creates a minimal markdown render context from an action. // If rendering fails, the original markdown text is returned -func renderMarkdown(ctx *context.Context, act *models.Action, content string) string { +func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) string { markdownCtx := &markup.RenderContext{ Ctx: ctx, URLPrefix: act.GetRepoLink(), @@ -67,7 +67,7 @@ func renderMarkdown(ctx *context.Context, act *models.Action, content string) st } // feedActionsToFeedItems convert gitea's Action feed to feeds Item -func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (items []*feeds.Item, err error) { +func feedActionsToFeedItems(ctx *context.Context, actions activities_model.ActionList) (items []*feeds.Item, err error) { for _, act := range actions { act.LoadActUser() @@ -78,110 +78,110 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it // title title = act.ActUser.DisplayName() + " " switch act.OpType { - case models.ActionCreateRepo: + case activities_model.ActionCreateRepo: title += ctx.TrHTMLEscapeArgs("action.create_repo", act.GetRepoLink(), act.ShortRepoPath()) link.Href = act.GetRepoLink() - case models.ActionRenameRepo: + case activities_model.ActionRenameRepo: title += ctx.TrHTMLEscapeArgs("action.rename_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath()) link.Href = act.GetRepoLink() - case models.ActionCommitRepo: + case activities_model.ActionCommitRepo: link.Href = toBranchLink(act) if len(act.Content) != 0 { title += ctx.TrHTMLEscapeArgs("action.commit_repo", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath()) } else { title += ctx.TrHTMLEscapeArgs("action.create_branch", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath()) } - case models.ActionCreateIssue: + case activities_model.ActionCreateIssue: link.Href = toIssueLink(act) title += ctx.TrHTMLEscapeArgs("action.create_issue", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionCreatePullRequest: + case activities_model.ActionCreatePullRequest: link.Href = toPullLink(act) title += ctx.TrHTMLEscapeArgs("action.create_pull_request", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionTransferRepo: + case activities_model.ActionTransferRepo: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.transfer_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath()) - case models.ActionPushTag: + case activities_model.ActionPushTag: link.Href = toTagLink(act) title += ctx.TrHTMLEscapeArgs("action.push_tag", act.GetRepoLink(), link.Href, act.GetTag(), act.ShortRepoPath()) - case models.ActionCommentIssue: + case activities_model.ActionCommentIssue: issueLink := toIssueLink(act) if link.Href == "#" { link.Href = issueLink } title += ctx.TrHTMLEscapeArgs("action.comment_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionMergePullRequest: + case activities_model.ActionMergePullRequest: pullLink := toPullLink(act) if link.Href == "#" { link.Href = pullLink } title += ctx.TrHTMLEscapeArgs("action.merge_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionCloseIssue: + case activities_model.ActionCloseIssue: issueLink := toIssueLink(act) if link.Href == "#" { link.Href = issueLink } title += ctx.TrHTMLEscapeArgs("action.close_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionReopenIssue: + case activities_model.ActionReopenIssue: issueLink := toIssueLink(act) if link.Href == "#" { link.Href = issueLink } title += ctx.TrHTMLEscapeArgs("action.reopen_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionClosePullRequest: + case activities_model.ActionClosePullRequest: pullLink := toPullLink(act) if link.Href == "#" { link.Href = pullLink } title += ctx.TrHTMLEscapeArgs("action.close_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionReopenPullRequest: + case activities_model.ActionReopenPullRequest: pullLink := toPullLink(act) if link.Href == "#" { link.Href = pullLink } title += ctx.TrHTMLEscapeArgs("action.reopen_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionDeleteTag: + case activities_model.ActionDeleteTag: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.delete_tag", act.GetRepoLink(), act.GetTag(), act.ShortRepoPath()) - case models.ActionDeleteBranch: + case activities_model.ActionDeleteBranch: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.delete_branch", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath()) - case models.ActionMirrorSyncPush: + case activities_model.ActionMirrorSyncPush: srcLink := toSrcLink(act) if link.Href == "#" { link.Href = srcLink } title += ctx.TrHTMLEscapeArgs("action.mirror_sync_push", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath()) - case models.ActionMirrorSyncCreate: + case activities_model.ActionMirrorSyncCreate: srcLink := toSrcLink(act) if link.Href == "#" { link.Href = srcLink } title += ctx.TrHTMLEscapeArgs("action.mirror_sync_create", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath()) - case models.ActionMirrorSyncDelete: + case activities_model.ActionMirrorSyncDelete: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.mirror_sync_delete", act.GetRepoLink(), act.GetBranch(), act.ShortRepoPath()) - case models.ActionApprovePullRequest: + case activities_model.ActionApprovePullRequest: pullLink := toPullLink(act) title += ctx.TrHTMLEscapeArgs("action.approve_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionRejectPullRequest: + case activities_model.ActionRejectPullRequest: pullLink := toPullLink(act) title += ctx.TrHTMLEscapeArgs("action.reject_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionCommentPull: + case activities_model.ActionCommentPull: pullLink := toPullLink(act) title += ctx.TrHTMLEscapeArgs("action.comment_pull", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath()) - case models.ActionPublishRelease: + case activities_model.ActionPublishRelease: releaseLink := toReleaseLink(act) if link.Href == "#" { link.Href = releaseLink } title += ctx.TrHTMLEscapeArgs("action.publish_release", act.GetRepoLink(), releaseLink, act.ShortRepoPath(), act.Content) - case models.ActionPullReviewDismissed: + case activities_model.ActionPullReviewDismissed: pullLink := toPullLink(act) title += ctx.TrHTMLEscapeArgs("action.review_dismissed", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath(), act.GetIssueInfos()[1]) - case models.ActionStarRepo: + case activities_model.ActionStarRepo: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.starred_repo", act.GetRepoLink(), act.GetRepoPath()) - case models.ActionWatchRepo: + case activities_model.ActionWatchRepo: link.Href = act.GetRepoLink() title += ctx.TrHTMLEscapeArgs("action.watched_repo", act.GetRepoLink(), act.GetRepoPath()) default: @@ -191,7 +191,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it // description & content { switch act.OpType { - case models.ActionCommitRepo, models.ActionMirrorSyncPush: + case activities_model.ActionCommitRepo, activities_model.ActionMirrorSyncPush: push := templates.ActionContent2Commits(act) repoLink := act.GetRepoLink() @@ -212,20 +212,20 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it link = &feeds.Link{Href: fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), push.Commits[0].Sha1)} } - case models.ActionCreateIssue, models.ActionCreatePullRequest: + case activities_model.ActionCreateIssue, activities_model.ActionCreatePullRequest: desc = strings.Join(act.GetIssueInfos(), "#") content = renderMarkdown(ctx, act, act.GetIssueContent()) - case models.ActionCommentIssue, models.ActionApprovePullRequest, models.ActionRejectPullRequest, models.ActionCommentPull: + case activities_model.ActionCommentIssue, activities_model.ActionApprovePullRequest, activities_model.ActionRejectPullRequest, activities_model.ActionCommentPull: desc = act.GetIssueTitle() comment := act.GetIssueInfos()[1] if len(comment) != 0 { desc += "\n\n" + renderMarkdown(ctx, act, comment) } - case models.ActionMergePullRequest: + case activities_model.ActionMergePullRequest: desc = act.GetIssueInfos()[1] - case models.ActionCloseIssue, models.ActionReopenIssue, models.ActionClosePullRequest, models.ActionReopenPullRequest: + case activities_model.ActionCloseIssue, activities_model.ActionReopenIssue, activities_model.ActionClosePullRequest, activities_model.ActionReopenPullRequest: desc = act.GetIssueTitle() - case models.ActionPullReviewDismissed: + case activities_model.ActionPullReviewDismissed: desc = ctx.Tr("action.review_dismissed_reason") + "\n\n" + act.GetIssueInfos()[2] } } diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index 61a39755f..c467f7412 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" "github.com/gorilla/feeds" @@ -26,7 +26,7 @@ func ShowUserFeedAtom(ctx *context.Context) { // showUserFeed show user activity as RSS / Atom feed func showUserFeed(ctx *context.Context, formatType string) { - actions, err := models.GetFeeds(ctx, models.GetFeedsOptions{ + actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: false, diff --git a/routers/web/feed/repo.go b/routers/web/feed/repo.go index ac856195b..027f90872 100644 --- a/routers/web/feed/repo.go +++ b/routers/web/feed/repo.go @@ -7,7 +7,7 @@ package feed import ( "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" @@ -16,7 +16,7 @@ import ( // ShowRepoFeed shows user activity on the repo as RSS / Atom feed func ShowRepoFeed(ctx *context.Context, repo *repo_model.Repository, formatType string) { - actions, err := models.GetFeeds(ctx, models.GetFeedsOptions{ + actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedRepo: repo, Actor: ctx.Doer, IncludePrivate: true, diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 9ee66a1a3..13c88565c 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -26,6 +26,7 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" "code.gitea.io/gitea/services/forms" + org_service "code.gitea.io/gitea/services/org" ) const ( @@ -194,7 +195,7 @@ func TeamsRepoAction(ctx *context.Context) { ctx.ServerError("GetRepositoryByName", err) return } - err = models.AddRepository(ctx.Org.Team, repo) + err = org_service.TeamAddRepository(ctx.Org.Team, repo) case "remove": err = models.RemoveRepository(ctx.Org.Team, ctx.FormInt64("repoid")) case "addall": @@ -339,7 +340,7 @@ func SearchTeam(ctx *context.Context) { } opts := &organization.SearchTeamOptions{ - UserID: ctx.Doer.ID, + // UserID is not set because the router already requires the doer to be an org admin. Thus, we don't need to restrict to teams that the user belongs in Keyword: ctx.FormTrim("q"), OrgID: ctx.Org.Organization.ID, IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"), diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go index b2f25ebe7..7f2ed8cb2 100644 --- a/routers/web/repo/activity.go +++ b/routers/web/repo/activity.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -52,7 +52,7 @@ func Activity(ctx *context.Context) { ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string)) var err error - if ctx.Data["Activity"], err = models.GetActivityStats(ctx, ctx.Repo.Repository, timeFrom, + if ctx.Data["Activity"], err = activities_model.GetActivityStats(ctx, ctx.Repo.Repository, timeFrom, ctx.Repo.CanRead(unit.TypeReleases), ctx.Repo.CanRead(unit.TypeIssues), ctx.Repo.CanRead(unit.TypePullRequests), @@ -61,7 +61,7 @@ func Activity(ctx *context.Context) { return } - if ctx.PageData["repoActivityTopAuthors"], err = models.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10); err != nil { + if ctx.PageData["repoActivityTopAuthors"], err = activities_model.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10); err != nil { ctx.ServerError("GetActivityStatsTopAuthors", err) return } @@ -94,7 +94,7 @@ func ActivityAuthors(ctx *context.Context) { } var err error - authors, err := models.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10) + authors, err := activities_model.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10) if err != nil { ctx.ServerError("GetActivityStatsTopAuthors", err) return diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 8ed794b45..e35af3172 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -17,7 +17,6 @@ import ( "path/filepath" "strings" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" @@ -459,7 +458,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { if rootRepo != nil && rootRepo.ID != ci.HeadRepo.ID && rootRepo.ID != baseRepo.ID { - canRead := models.CheckRepoUnitUser(ctx, rootRepo, ctx.Doer, unit.TypeCode) + canRead := access_model.CheckRepoUnitUser(ctx, rootRepo, ctx.Doer, unit.TypeCode) if canRead { ctx.Data["RootRepo"] = rootRepo if !fileOnly { @@ -484,7 +483,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { ownForkRepo.ID != ci.HeadRepo.ID && ownForkRepo.ID != baseRepo.ID && (rootRepo == nil || ownForkRepo.ID != rootRepo.ID) { - canRead := models.CheckRepoUnitUser(ctx, ownForkRepo, ctx.Doer, unit.TypeCode) + canRead := access_model.CheckRepoUnitUser(ctx, ownForkRepo, ctx.Doer, unit.TypeCode) if canRead { ctx.Data["OwnForkRepo"] = ownForkRepo if !fileOnly { @@ -785,7 +784,11 @@ func CompareDiff(ctx *context.Context) { ctx.Data["IsRepoToolbarCommits"] = true ctx.Data["IsDiffCompare"] = true ctx.Data["RequireTribute"] = true - setTemplateIfExists(ctx, pullRequestTemplateKey, nil, pullRequestTemplateCandidates) + templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates) + + if len(templateErrs) > 0 { + ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true) + } // If a template content is set, prepend the "content". In this case that's only // applicable if you have one commit to compare and that commit has a message. diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index b510fd504..e8fc02045 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" @@ -763,7 +764,7 @@ func UploadFileToServer(ctx *context.Context) { return } - upload, err := models.NewUpload(name, buf, file) + upload, err := repo_model.NewUpload(name, buf, file) if err != nil { ctx.Error(http.StatusInternalServerError, fmt.Sprintf("NewUpload: %v", err)) return @@ -783,7 +784,7 @@ func RemoveUploadFileFromServer(ctx *context.Context) { return } - if err := models.DeleteUploadByUUID(form.File); err != nil { + if err := repo_model.DeleteUploadByUUID(form.File); err != nil { ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteUploadByUUID: %v", err)) return } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index ad25a94e1..06e003bff 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -10,16 +10,15 @@ import ( stdCtx "context" "errors" "fmt" - "io" "math/big" "net/http" "net/url" - "path" + "sort" "strconv" "strings" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" @@ -35,6 +34,7 @@ import ( "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" + issue_template "code.gitea.io/gitea/modules/issue/template" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" @@ -45,6 +45,7 @@ import ( "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" comment_service "code.gitea.io/gitea/services/comments" "code.gitea.io/gitea/services/forms" @@ -70,11 +71,23 @@ const ( // IssueTemplateCandidates issue templates var IssueTemplateCandidates = []string{ "ISSUE_TEMPLATE.md", + "ISSUE_TEMPLATE.yaml", + "ISSUE_TEMPLATE.yml", "issue_template.md", + "issue_template.yaml", + "issue_template.yml", ".gitea/ISSUE_TEMPLATE.md", + ".gitea/ISSUE_TEMPLATE.yaml", + ".gitea/ISSUE_TEMPLATE.yml", + ".gitea/issue_template.md", + ".gitea/issue_template.yaml", ".gitea/issue_template.md", ".github/ISSUE_TEMPLATE.md", + ".github/ISSUE_TEMPLATE.yaml", + ".github/ISSUE_TEMPLATE.yml", ".github/issue_template.md", + ".github/issue_template.yaml", + ".github/issue_template.yml", } // MustAllowUserComment checks to make sure if an issue is locked. @@ -722,81 +735,62 @@ func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull return labels } -func getFileContentFromDefaultBranch(ctx *context.Context, filename string) (string, bool) { - if ctx.Repo.Commit == nil { - var err error - ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) - if err != nil { - return "", false - } +func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles []string) map[string]error { + commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) + if err != nil { + return nil } - entry, err := ctx.Repo.Commit.GetTreeEntryByPath(filename) - if err != nil { - return "", false - } - if entry.Blob().Size() >= setting.UI.MaxDisplayFileSize { - return "", false - } - r, err := entry.Blob().DataAsync() - if err != nil { - return "", false - } - defer r.Close() - bytes, err := io.ReadAll(r) - if err != nil { - return "", false - } - return string(bytes), true -} - -func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleDirs, possibleFiles []string) { - templateCandidates := make([]string, 0, len(possibleFiles)) - if ctx.FormString("template") != "" { - for _, dirName := range possibleDirs { - templateCandidates = append(templateCandidates, path.Join(dirName, ctx.FormString("template"))) - } + templateCandidates := make([]string, 0, 1+len(possibleFiles)) + if t := ctx.FormString("template"); t != "" { + templateCandidates = append(templateCandidates, t) } templateCandidates = append(templateCandidates, possibleFiles...) // Append files to the end because they should be fallback - for _, filename := range templateCandidates { - templateContent, found := getFileContentFromDefaultBranch(ctx, filename) - if found { - var meta api.IssueTemplate - templateBody, err := markdown.ExtractMetadata(templateContent, &meta) - if err != nil { - log.Debug("could not extract metadata from %s [%s]: %v", filename, ctx.Repo.Repository.FullName(), err) - ctx.Data[ctxDataKey] = templateContent - return - } - ctx.Data[issueTemplateTitleKey] = meta.Title - ctx.Data[ctxDataKey] = templateBody - labelIDs := make([]string, 0, len(meta.Labels)) - if repoLabels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { - ctx.Data["Labels"] = repoLabels - if ctx.Repo.Owner.IsOrganization() { - if orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { - ctx.Data["OrgLabels"] = orgLabels - repoLabels = append(repoLabels, orgLabels...) - } - } - for _, metaLabel := range meta.Labels { - for _, repoLabel := range repoLabels { - if strings.EqualFold(repoLabel.Name, metaLabel) { - repoLabel.IsChecked = true - labelIDs = append(labelIDs, strconv.FormatInt(repoLabel.ID, 10)) - break - } + templateErrs := map[string]error{} + for _, filename := range templateCandidates { + if ok, _ := commit.HasFile(filename); !ok { + continue + } + template, err := issue_template.UnmarshalFromCommit(commit, filename) + if err != nil { + templateErrs[filename] = err + continue + } + ctx.Data[issueTemplateTitleKey] = template.Title + ctx.Data[ctxDataKey] = template.Content + + if template.Type() == api.IssueTemplateTypeYaml { + ctx.Data["Fields"] = template.Fields + ctx.Data["TemplateFile"] = template.FileName + } + labelIDs := make([]string, 0, len(template.Labels)) + if repoLabels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { + ctx.Data["Labels"] = repoLabels + if ctx.Repo.Owner.IsOrganization() { + if orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { + ctx.Data["OrgLabels"] = orgLabels + repoLabels = append(repoLabels, orgLabels...) + } + } + + for _, metaLabel := range template.Labels { + for _, repoLabel := range repoLabels { + if strings.EqualFold(repoLabel.Name, metaLabel) { + repoLabel.IsChecked = true + labelIDs = append(labelIDs, strconv.FormatInt(repoLabel.ID, 10)) + break } } } - ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0 - ctx.Data["label_ids"] = strings.Join(labelIDs, ",") - ctx.Data["Reference"] = meta.Ref - ctx.Data["RefEndName"] = git.RefEndName(meta.Ref) - return } + ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0 + ctx.Data["label_ids"] = strings.Join(labelIDs, ",") + ctx.Data["Reference"] = template.Ref + ctx.Data["RefEndName"] = git.RefEndName(template.Ref) + return templateErrs } + return templateErrs } // NewIssue render creating issue page @@ -845,24 +839,62 @@ func NewIssue(ctx *context.Context) { } RetrieveRepoMetas(ctx, ctx.Repo.Repository, false) - setTemplateIfExists(ctx, issueTemplateKey, context.IssueTemplateDirCandidates, IssueTemplateCandidates) + + _, templateErrs := ctx.IssueTemplatesErrorsFromDefaultBranch() + if errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates); len(errs) > 0 { + for k, v := range errs { + templateErrs[k] = v + } + } if ctx.Written() { return } + if len(templateErrs) > 0 { + ctx.Flash.Warning(renderErrorOfTemplates(ctx, templateErrs), true) + } + ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWrite(unit.TypeIssues) ctx.HTML(http.StatusOK, tplIssueNew) } +func renderErrorOfTemplates(ctx *context.Context, errs map[string]error) string { + var files []string + for k := range errs { + files = append(files, k) + } + sort.Strings(files) // keep the output stable + + var lines []string + for _, file := range files { + lines = append(lines, fmt.Sprintf("%s: %v", file, errs[file])) + } + + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + "Message": ctx.Tr("repo.issues.choose.ignore_invalid_templates"), + "Summary": ctx.Tr("repo.issues.choose.invalid_templates", len(errs)), + "Details": utils.SanitizeFlashErrorString(strings.Join(lines, "\n")), + }) + if err != nil { + log.Debug("render flash error: %v", err) + flashError = ctx.Tr("repo.issues.choose.ignore_invalid_templates") + } + return flashError +} + // NewIssueChooseTemplate render creating issue from template page func NewIssueChooseTemplate(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.issues.new") ctx.Data["PageIsIssueList"] = true - issueTemplates := ctx.IssueTemplatesFromDefaultBranch() + issueTemplates, errs := ctx.IssueTemplatesErrorsFromDefaultBranch() ctx.Data["IssueTemplates"] = issueTemplates + if len(errs) > 0 { + ctx.Flash.Warning(renderErrorOfTemplates(ctx, errs), true) + } + if len(issueTemplates) == 0 { // The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters. ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.HTMLURL(), ctx.Req.URL.RawQuery), http.StatusSeeOther) @@ -1031,6 +1063,13 @@ func NewIssuePost(ctx *context.Context) { return } + content := form.Content + if filename := ctx.Req.Form.Get("template-file"); filename != "" { + if template, err := issue_template.UnmarshalFromRepo(ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil { + content = issue_template.RenderToMarkdown(template, ctx.Req.Form) + } + } + issue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, @@ -1038,7 +1077,7 @@ func NewIssuePost(ctx *context.Context) { PosterID: ctx.Doer.ID, Poster: ctx.Doer, MilestoneID: milestoneID, - Content: form.Content, + Content: content, Ref: form.Ref, } @@ -1313,7 +1352,7 @@ func ViewIssue(ctx *context.Context) { if ctx.IsSigned { // Update issue-user. - if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { + if err = activities_model.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 7c140a4e5..aa2c4cdb5 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -17,6 +17,7 @@ import ( "time" "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" @@ -29,6 +30,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + issue_template "code.gitea.io/gitea/modules/issue/template" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" @@ -57,11 +59,23 @@ const ( var pullRequestTemplateCandidates = []string{ "PULL_REQUEST_TEMPLATE.md", + "PULL_REQUEST_TEMPLATE.yaml", + "PULL_REQUEST_TEMPLATE.yml", "pull_request_template.md", + "pull_request_template.yaml", + "pull_request_template.yml", ".gitea/PULL_REQUEST_TEMPLATE.md", + ".gitea/PULL_REQUEST_TEMPLATE.yaml", + ".gitea/PULL_REQUEST_TEMPLATE.yml", ".gitea/pull_request_template.md", + ".gitea/pull_request_template.yaml", + ".gitea/pull_request_template.yml", ".github/PULL_REQUEST_TEMPLATE.md", + ".github/PULL_REQUEST_TEMPLATE.yaml", + ".github/PULL_REQUEST_TEMPLATE.yml", ".github/pull_request_template.md", + ".github/pull_request_template.yaml", + ".github/pull_request_template.yml", } func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { @@ -295,7 +309,7 @@ func checkPullInfo(ctx *context.Context) *issues_model.Issue { if ctx.IsSigned { // Update issue-user. - if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { + if err = activities_model.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return nil } @@ -1193,6 +1207,13 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } + content := form.Content + if filename := ctx.Req.Form.Get("template-file"); filename != "" { + if template, err := issue_template.UnmarshalFromRepo(ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil { + content = issue_template.RenderToMarkdown(template, ctx.Req.Form) + } + } + pullIssue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, @@ -1201,7 +1222,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { Poster: ctx.Doer, MilestoneID: milestoneID, IsPull: true, - Content: form.Content, + Content: content, } pullRequest := &issues_model.PullRequest{ HeadRepoID: ci.HeadRepo.ID, diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index ab87c3e23..935813051 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -33,7 +34,7 @@ const ( ) // calReleaseNumCommitsBehind calculates given release has how many commits behind release target. -func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *models.Release, countCache map[string]int64) error { +func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *repo_model.Release, countCache map[string]int64) error { // Fast return if release target is same as default branch. if repoCtx.BranchName == release.Target { release.NumCommitsBehind = repoCtx.CommitsCount - release.NumCommits @@ -115,25 +116,25 @@ func releasesOrTags(ctx *context.Context, isTagList bool) { writeAccess := ctx.Repo.CanWrite(unit.TypeReleases) ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived - opts := models.FindReleasesOptions{ + opts := repo_model.FindReleasesOptions{ ListOptions: listOptions, IncludeDrafts: writeAccess && !isTagList, IncludeTags: isTagList, } - releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) + releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) if err != nil { ctx.ServerError("GetReleasesByRepoID", err) return } - count, err := models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, opts) + count, err := repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, opts) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) return } - if err = models.GetReleaseAttachments(ctx, releases...); err != nil { + if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil { ctx.ServerError("GetReleaseAttachments", err) return } @@ -199,9 +200,9 @@ func SingleRelease(ctx *context.Context) { writeAccess := ctx.Repo.CanWrite(unit.TypeReleases) ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived - release, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params("*")) + release, err := repo_model.GetRelease(ctx.Repo.Repository.ID, ctx.Params("*")) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound("GetRelease", err) return } @@ -209,7 +210,7 @@ func SingleRelease(ctx *context.Context) { return } - err = models.GetReleaseAttachments(ctx, release) + err = repo_model.GetReleaseAttachments(ctx, release) if err != nil { ctx.ServerError("GetReleaseAttachments", err) return @@ -241,15 +242,15 @@ func SingleRelease(ctx *context.Context) { return } - ctx.Data["Releases"] = []*models.Release{release} + ctx.Data["Releases"] = []*repo_model.Release{release} ctx.HTML(http.StatusOK, tplReleases) } // LatestRelease redirects to the latest release func LatestRelease(ctx *context.Context) { - release, err := models.GetLatestReleaseByRepoID(ctx.Repo.Repository.ID) + release, err := repo_model.GetLatestReleaseByRepoID(ctx.Repo.Repository.ID) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound("LatestRelease", err) return } @@ -272,8 +273,8 @@ func NewRelease(ctx *context.Context) { ctx.Data["RequireTribute"] = true ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch if tagName := ctx.FormString("tag"); len(tagName) > 0 { - rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName) - if err != nil && !models.IsErrReleaseNotExist(err) { + rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) + if err != nil && !repo_model.IsErrReleaseNotExist(err) { ctx.ServerError("GetRelease", err) return } @@ -321,9 +322,9 @@ func NewReleasePost(ctx *context.Context) { attachmentUUIDs = form.Files } - rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName) + rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, form.TagName) if err != nil { - if !models.IsErrReleaseNotExist(err) { + if !repo_model.IsErrReleaseNotExist(err) { ctx.ServerError("GetRelease", err) return } @@ -363,7 +364,7 @@ func NewReleasePost(ctx *context.Context) { return } - rel = &models.Release{ + rel = &repo_model.Release{ RepoID: ctx.Repo.Repository.ID, Repo: ctx.Repo.Repository, PublisherID: ctx.Doer.ID, @@ -380,7 +381,7 @@ func NewReleasePost(ctx *context.Context) { if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs, msg); err != nil { ctx.Data["Err_TagName"] = true switch { - case models.IsErrReleaseAlreadyExist(err): + case repo_model.IsErrReleaseAlreadyExist(err): ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), tplReleaseNew, &form) case models.IsErrInvalidTagName(err): ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_invalid"), tplReleaseNew, &form) @@ -427,9 +428,9 @@ func EditRelease(ctx *context.Context) { upload.AddUploadContext(ctx, "release") tagName := ctx.Params("*") - rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName) + rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound("GetRelease", err) } else { ctx.ServerError("GetRelease", err) @@ -463,9 +464,9 @@ func EditReleasePost(ctx *context.Context) { ctx.Data["RequireTribute"] = true tagName := ctx.Params("*") - rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName) + rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) if err != nil { - if models.IsErrReleaseNotExist(err) { + if repo_model.IsErrReleaseNotExist(err) { ctx.NotFound("GetRelease", err) } else { ctx.ServerError("GetRelease", err) diff --git a/routers/web/repo/release_test.go b/routers/web/repo/release_test.go index 33cf54cdc..16371fc86 100644 --- a/routers/web/repo/release_test.go +++ b/routers/web/repo/release_test.go @@ -7,7 +7,7 @@ package repo import ( "testing" - "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/web" @@ -52,7 +52,7 @@ func TestNewReleasePost(t *testing.T) { test.LoadGitRepo(t, ctx) web.SetForm(ctx, &testCase.Form) NewReleasePost(ctx) - unittest.AssertExistsAndLoadBean(t, &models.Release{ + unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ RepoID: 1, PublisherID: 2, TagName: testCase.Form.TagName, diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index c2c79e4a0..974f03f95 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -10,18 +10,17 @@ import ( "fmt" "net/http" "strings" - "time" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" - "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -152,7 +151,7 @@ func Create(ctx *context.Context) { templateID := ctx.FormInt64("template_id") if templateID > 0 { templateRepo, err := repo_model.GetRepositoryByID(templateID) - if err == nil && models.CheckRepoUnitUser(ctx, templateRepo, ctxUser, unit.TypeCode) { + if err == nil && access_model.CheckRepoUnitUser(ctx, templateRepo, ctxUser, unit.TypeCode) { ctx.Data["repo_template"] = templateID ctx.Data["repo_template_name"] = templateRepo.Name } @@ -257,7 +256,7 @@ func CreatePost(ctx *context.Context) { return } } else { - repo, err = repo_service.CreateRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{ + repo, err = repo_service.CreateRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ Name: form.RepoName, Description: form.Description, Gitignores: form.Gitignores, @@ -358,7 +357,7 @@ func RedirectDownload(ctx *context.Context) { ) tagNames := []string{vTag} curRepo := ctx.Repo.Repository - releases, err := models.GetReleasesByRepoIDAndNames(ctx, curRepo.ID, tagNames) + releases, err := repo_model.GetReleasesByRepoIDAndNames(ctx, curRepo.ID, tagNames) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { ctx.Error(http.StatusNotFound) @@ -389,68 +388,27 @@ func Download(ctx *context.Context) { if err != nil { if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { ctx.Error(http.StatusBadRequest, err.Error()) + } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) { + ctx.Error(http.StatusNotFound, err.Error()) } else { ctx.ServerError("archiver_service.NewRequest", err) } return } - if aReq == nil { - ctx.Error(http.StatusNotFound) - return - } - archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID) + archiver, err := aReq.Await(ctx) if err != nil { - ctx.ServerError("models.GetRepoArchiver", err) - return - } - if archiver != nil && archiver.Status == repo_model.ArchiverReady { - download(ctx, aReq.GetArchiveName(), archiver) + ctx.ServerError("archiver.Await", err) return } - if err := archiver_service.StartArchive(aReq); err != nil { - ctx.ServerError("archiver_service.StartArchive", err) - return - } - - var times int - t := time.NewTicker(time.Second * 1) - defer t.Stop() - - for { - select { - case <-graceful.GetManager().HammerContext().Done(): - log.Warn("exit archive download because system stop") - return - case <-t.C: - if times > 20 { - ctx.ServerError("wait download timeout", nil) - return - } - times++ - archiver, err = repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID) - if err != nil { - ctx.ServerError("archiver_service.StartArchive", err) - return - } - if archiver != nil && archiver.Status == repo_model.ArchiverReady { - download(ctx, aReq.GetArchiveName(), archiver) - return - } - } - } + download(ctx, aReq.GetArchiveName(), archiver) } func download(ctx *context.Context, archiveName string, archiver *repo_model.RepoArchiver) { downloadName := ctx.Repo.Repository.Name + "-" + archiveName - rPath, err := archiver.RelativePath() - if err != nil { - ctx.ServerError("archiver.RelativePath", err) - return - } - + rPath := archiver.RelativePath() if setting.RepoArchive.ServeDirect { // If we have a signed url (S3, object storage), redirect to this directly. u, err := storage.RepoArchives.URL(rPath, downloadName) @@ -467,7 +425,8 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep return } defer fr.Close() - ctx.ServeStream(fr, downloadName) + + ctx.ServeContent(downloadName, fr, archiver.CreatedUnix.AsLocalTime()) } // InitiateDownload will enqueue an archival request, as needed. It may submit diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index a59824cec..267940c8d 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -30,7 +30,7 @@ import ( "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" mirror_module "code.gitea.io/gitea/modules/mirror" - "code.gitea.io/gitea/modules/repository" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/typesniffer" @@ -43,6 +43,7 @@ import ( "code.gitea.io/gitea/services/mailer" "code.gitea.io/gitea/services/migrations" mirror_service "code.gitea.io/gitea/services/mirror" + org_service "code.gitea.io/gitea/services/org" repo_service "code.gitea.io/gitea/services/repository" wiki_service "code.gitea.io/gitea/services/wiki" ) @@ -228,14 +229,17 @@ func SettingsPost(ctx *context.Context) { form.MirrorPassword, _ = u.User.Password() } - err = migrations.IsMigrateURLAllowed(u.String(), ctx.Doer) + address, err := forms.ParseRemoteAddr(form.MirrorAddress, form.MirrorUsername, form.MirrorPassword) + if err == nil { + err = migrations.IsMigrateURLAllowed(address, ctx.Doer) + } if err != nil { ctx.Data["Err_MirrorAddress"] = true handleSettingRemoteAddrError(ctx, err, form) return } - if err := mirror_service.UpdateAddress(ctx, ctx.Repo.Mirror, u.String()); err != nil { + if err := mirror_service.UpdateAddress(ctx, ctx.Repo.Mirror, address); err != nil { ctx.ServerError("UpdateAddress", err) return } @@ -604,7 +608,7 @@ func SettingsPost(ctx *context.Context) { } repo.IsMirror = false - if _, err := repository.CleanUpMigrateInfo(ctx, repo); err != nil { + if _, err := repo_module.CleanUpMigrateInfo(ctx, repo); err != nil { ctx.ServerError("CleanUpMigrateInfo", err) return } else if err = repo_model.DeleteMirrorByRepoID(ctx.Repo.Repository.ID); err != nil { @@ -913,7 +917,7 @@ func CollaborationPost(ctx *context.Context) { return } - if err = models.AddCollaborator(ctx.Repo.Repository, u); err != nil { + if err = repo_module.AddCollaborator(ctx.Repo.Repository, u); err != nil { ctx.ServerError("AddCollaborator", err) return } @@ -986,8 +990,8 @@ func AddTeamPost(ctx *context.Context) { return } - if err = models.AddRepository(team, ctx.Repo.Repository); err != nil { - ctx.ServerError("team.AddRepository", err) + if err = org_service.TeamAddRepository(team, ctx.Repo.Repository); err != nil { + ctx.ServerError("TeamAddRepository", err) return } diff --git a/routers/web/repo/settings_test.go b/routers/web/repo/settings_test.go index 946220b4f..4acd7df5b 100644 --- a/routers/web/repo/settings_test.go +++ b/routers/web/repo/settings_test.go @@ -6,7 +6,6 @@ package repo import ( "net/http" - "os" "testing" "code.gitea.io/gitea/models" @@ -19,7 +18,6 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" @@ -27,18 +25,13 @@ import ( ) func createSSHAuthorizedKeysTmpPath(t *testing.T) func() { - tmpDir, err := os.MkdirTemp("", "tmp-ssh") - if err != nil { - assert.Fail(t, "Unable to create temporary directory: %v", err) - return nil - } + tmpDir := t.TempDir() oldPath := setting.SSH.RootPath setting.SSH.RootPath = tmpDir return func() { setting.SSH.RootPath = oldPath - util.RemoveAll(tmpDir) } } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 72ffda7e0..24f559fe4 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -18,7 +18,8 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" + admin_model "code.gitea.io/gitea/models/admin" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" @@ -666,9 +667,9 @@ func safeURL(address string) string { func checkHomeCodeViewable(ctx *context.Context) { if len(ctx.Repo.Units) > 0 { if ctx.Repo.Repository.IsBeingCreated() { - task, err := models.GetMigratingTask(ctx.Repo.Repository.ID) + task, err := admin_model.GetMigratingTask(ctx.Repo.Repository.ID) if err != nil { - if models.IsErrTaskDoesNotExist(err) { + if admin_model.IsErrTaskDoesNotExist(err) { ctx.Data["Repo"] = ctx.Repo ctx.Data["CloneAddr"] = "" ctx.Data["Failed"] = true @@ -694,7 +695,7 @@ func checkHomeCodeViewable(ctx *context.Context) { if ctx.IsSigned { // Set repo notification-status read if unread - if err := models.SetRepoReadBy(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID); err != nil { + if err := activities_model.SetRepoReadBy(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return } diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go index d4419a1e1..a8939e72b 100644 --- a/routers/web/repo/webhook.go +++ b/routers/web/repo/webhook.go @@ -178,6 +178,7 @@ func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent { PullRequestComment: form.PullRequestComment, PullRequestReview: form.PullRequestReview, PullRequestSync: form.PullRequestSync, + Wiki: form.Wiki, Repository: form.Repository, Package: form.Package, }, @@ -185,17 +186,19 @@ func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent { } } -type webhookCreationParams struct { +type webhookParams struct { + // Type should be imported from webhook package (webhook.XXX) + Type string + URL string ContentType webhook.HookContentType Secret string HTTPMethod string WebhookForm forms.WebhookForm - Type string Meta interface{} } -func createWebhook(ctx *context.Context, params webhookCreationParams) { +func createWebhook(ctx *context.Context, params webhookParams) { ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooksNew"] = true @@ -248,8 +251,63 @@ func createWebhook(ctx *context.Context, params webhookCreationParams) { ctx.Redirect(orCtx.Link) } +func editWebhook(ctx *context.Context, params webhookParams) { + ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") + ctx.Data["PageIsSettingsHooks"] = true + ctx.Data["PageIsSettingsHooksEdit"] = true + + orCtx, w := checkWebhook(ctx) + if ctx.Written() { + return + } + ctx.Data["Webhook"] = w + + if ctx.HasError() { + ctx.HTML(http.StatusOK, orCtx.NewTemplate) + return + } + + var meta []byte + var err error + if params.Meta != nil { + meta, err = json.Marshal(params.Meta) + if err != nil { + ctx.ServerError("Marshal", err) + return + } + } + + w.URL = params.URL + w.ContentType = params.ContentType + w.Secret = params.Secret + w.HookEvent = ParseHookEvent(params.WebhookForm) + w.IsActive = params.WebhookForm.Active + w.HTTPMethod = params.HTTPMethod + w.Meta = string(meta) + + if err := w.UpdateEvent(); err != nil { + ctx.ServerError("UpdateEvent", err) + return + } else if err := webhook.UpdateWebhook(w); err != nil { + ctx.ServerError("UpdateWebhook", err) + return + } + + ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) + ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) +} + // GiteaHooksNewPost response for creating Gitea webhook func GiteaHooksNewPost(ctx *context.Context) { + createWebhook(ctx, giteaHookParams(ctx)) +} + +// GiteaHooksEditPost response for editing Gitea webhook +func GiteaHooksEditPost(ctx *context.Context) { + editWebhook(ctx, giteaHookParams(ctx)) +} + +func giteaHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewWebhookForm) contentType := webhook.ContentTypeJSON @@ -257,18 +315,27 @@ func GiteaHooksNewPost(ctx *context.Context) { contentType = webhook.ContentTypeForm } - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.GITEA, URL: form.PayloadURL, ContentType: contentType, Secret: form.Secret, HTTPMethod: form.HTTPMethod, WebhookForm: form.WebhookForm, - Type: webhook.GITEA, - }) + } } -// GogsHooksNewPost response for creating webhook +// GogsHooksNewPost response for creating Gogs webhook func GogsHooksNewPost(ctx *context.Context) { + createWebhook(ctx, gogsHookParams(ctx)) +} + +// GogsHooksEditPost response for editing Gogs webhook +func GogsHooksEditPost(ctx *context.Context) { + editWebhook(ctx, gogsHookParams(ctx)) +} + +func gogsHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewGogshookForm) contentType := webhook.ContentTypeJSON @@ -276,147 +343,228 @@ func GogsHooksNewPost(ctx *context.Context) { contentType = webhook.ContentTypeForm } - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.GOGS, URL: form.PayloadURL, ContentType: contentType, Secret: form.Secret, WebhookForm: form.WebhookForm, - Type: webhook.GOGS, - }) + } } -// DiscordHooksNewPost response for creating discord hook +// DiscordHooksNewPost response for creating Discord webhook func DiscordHooksNewPost(ctx *context.Context) { + createWebhook(ctx, discordHookParams(ctx)) +} + +// DiscordHooksEditPost response for editing Discord webhook +func DiscordHooksEditPost(ctx *context.Context) { + editWebhook(ctx, discordHookParams(ctx)) +} + +func discordHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewDiscordHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.DISCORD, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.DISCORD, Meta: &webhook_service.DiscordMeta{ Username: form.Username, IconURL: form.IconURL, }, - }) + } } -// DingtalkHooksNewPost response for creating dingtalk hook +// DingtalkHooksNewPost response for creating Dingtalk webhook func DingtalkHooksNewPost(ctx *context.Context) { + createWebhook(ctx, dingtalkHookParams(ctx)) +} + +// DingtalkHooksEditPost response for editing Dingtalk webhook +func DingtalkHooksEditPost(ctx *context.Context) { + editWebhook(ctx, dingtalkHookParams(ctx)) +} + +func dingtalkHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewDingtalkHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.DINGTALK, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.DINGTALK, - }) + } } -// TelegramHooksNewPost response for creating telegram hook +// TelegramHooksNewPost response for creating Telegram webhook func TelegramHooksNewPost(ctx *context.Context) { + createWebhook(ctx, telegramHookParams(ctx)) +} + +// TelegramHooksEditPost response for editing Telegram webhook +func TelegramHooksEditPost(ctx *context.Context) { + editWebhook(ctx, telegramHookParams(ctx)) +} + +func telegramHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewTelegramHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.TELEGRAM, URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)), ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.TELEGRAM, Meta: &webhook_service.TelegramMeta{ BotToken: form.BotToken, ChatID: form.ChatID, }, - }) + } } -// MatrixHooksNewPost response for creating a Matrix hook +// MatrixHooksNewPost response for creating Matrix webhook func MatrixHooksNewPost(ctx *context.Context) { + createWebhook(ctx, matrixHookParams(ctx)) +} + +// MatrixHooksEditPost response for editing Matrix webhook +func MatrixHooksEditPost(ctx *context.Context) { + editWebhook(ctx, matrixHookParams(ctx)) +} + +func matrixHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewMatrixHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.MATRIX, URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), ContentType: webhook.ContentTypeJSON, HTTPMethod: http.MethodPut, WebhookForm: form.WebhookForm, - Type: webhook.MATRIX, Meta: &webhook_service.MatrixMeta{ HomeserverURL: form.HomeserverURL, Room: form.RoomID, AccessToken: form.AccessToken, MessageType: form.MessageType, }, - }) + } } -// MSTeamsHooksNewPost response for creating MS Teams hook +// MSTeamsHooksNewPost response for creating MSTeams webhook func MSTeamsHooksNewPost(ctx *context.Context) { + createWebhook(ctx, mSTeamsHookParams(ctx)) +} + +// MSTeamsHooksEditPost response for editing MSTeams webhook +func MSTeamsHooksEditPost(ctx *context.Context) { + editWebhook(ctx, mSTeamsHookParams(ctx)) +} + +func mSTeamsHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.MSTEAMS, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.MSTEAMS, - }) + } } -// SlackHooksNewPost response for creating slack hook +// SlackHooksNewPost response for creating Slack webhook func SlackHooksNewPost(ctx *context.Context) { + createWebhook(ctx, slackHookParams(ctx)) +} + +// SlackHooksEditPost response for editing Slack webhook +func SlackHooksEditPost(ctx *context.Context) { + editWebhook(ctx, slackHookParams(ctx)) +} + +func slackHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewSlackHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.SLACK, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.SLACK, Meta: &webhook_service.SlackMeta{ Channel: strings.TrimSpace(form.Channel), Username: form.Username, IconURL: form.IconURL, Color: form.Color, }, - }) + } } -// FeishuHooksNewPost response for creating feishu hook +// FeishuHooksNewPost response for creating Feishu webhook func FeishuHooksNewPost(ctx *context.Context) { + createWebhook(ctx, feishuHookParams(ctx)) +} + +// FeishuHooksEditPost response for editing Feishu webhook +func FeishuHooksEditPost(ctx *context.Context) { + editWebhook(ctx, feishuHookParams(ctx)) +} + +func feishuHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewFeishuHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.FEISHU, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.FEISHU, - }) + } } -// WechatworkHooksNewPost response for creating wechatwork hook +// WechatworkHooksNewPost response for creating Wechatwork webhook func WechatworkHooksNewPost(ctx *context.Context) { + createWebhook(ctx, wechatworkHookParams(ctx)) +} + +// WechatworkHooksEditPost response for editing Wechatwork webhook +func WechatworkHooksEditPost(ctx *context.Context) { + editWebhook(ctx, wechatworkHookParams(ctx)) +} + +func wechatworkHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.WECHATWORK, URL: form.PayloadURL, ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.WECHATWORK, - }) + } } -// PackagistHooksNewPost response for creating packagist hook +// PackagistHooksNewPost response for creating Packagist webhook func PackagistHooksNewPost(ctx *context.Context) { + createWebhook(ctx, packagistHookParams(ctx)) +} + +// PackagistHooksEditPost response for editing Packagist webhook +func PackagistHooksEditPost(ctx *context.Context) { + editWebhook(ctx, packagistHookParams(ctx)) +} + +func packagistHookParams(ctx *context.Context) webhookParams { form := web.GetForm(ctx).(*forms.NewPackagistHookForm) - createWebhook(ctx, webhookCreationParams{ + return webhookParams{ + Type: webhook.PACKAGIST, URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), ContentType: webhook.ContentTypeJSON, WebhookForm: form.WebhookForm, - Type: webhook.PACKAGIST, Meta: &webhook_service.PackagistMeta{ Username: form.Username, APIToken: form.APIToken, PackageURL: form.PackageURL, }, - }) + } } func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) { @@ -480,438 +628,6 @@ func WebHooksEdit(ctx *context.Context) { ctx.HTML(http.StatusOK, orCtx.NewTemplate) } -// WebHooksEditPost response for editing web hook -func WebHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewWebhookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - contentType := webhook.ContentTypeJSON - if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { - contentType = webhook.ContentTypeForm - } - - w.URL = form.PayloadURL - w.ContentType = contentType - w.Secret = form.Secret - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - w.HTTPMethod = form.HTTPMethod - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("WebHooksEditPost", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// GogsHooksEditPost response for editing gogs hook -func GogsHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewGogshookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - contentType := webhook.ContentTypeJSON - if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { - contentType = webhook.ContentTypeForm - } - - w.URL = form.PayloadURL - w.ContentType = contentType - w.Secret = form.Secret - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("GogsHooksEditPost", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// SlackHooksEditPost response for editing slack hook -func SlackHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewSlackHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.SlackMeta{ - Channel: strings.TrimSpace(form.Channel), - Username: form.Username, - IconURL: form.IconURL, - Color: form.Color, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w.URL = form.PayloadURL - w.Meta = string(meta) - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// DiscordHooksEditPost response for editing discord hook -func DiscordHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewDiscordHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.DiscordMeta{ - Username: form.Username, - IconURL: form.IconURL, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w.URL = form.PayloadURL - w.Meta = string(meta) - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// DingtalkHooksEditPost response for editing discord hook -func DingtalkHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewDingtalkHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w.URL = form.PayloadURL - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// TelegramHooksEditPost response for editing discord hook -func TelegramHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewTelegramHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.TelegramMeta{ - BotToken: form.BotToken, - ChatID: form.ChatID, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - w.Meta = string(meta) - w.URL = fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)) - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// MatrixHooksEditPost response for editing a Matrix hook -func MatrixHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewMatrixHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.MatrixMeta{ - HomeserverURL: form.HomeserverURL, - Room: form.RoomID, - AccessToken: form.AccessToken, - MessageType: form.MessageType, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - w.Meta = string(meta) - w.URL = fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)) - - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// MSTeamsHooksEditPost response for editing MS Teams hook -func MSTeamsHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w.URL = form.PayloadURL - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// FeishuHooksEditPost response for editing feishu hook -func FeishuHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewFeishuHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w.URL = form.PayloadURL - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// WechatworkHooksEditPost response for editing wechatwork hook -func WechatworkHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - w.URL = form.PayloadURL - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - -// PackagistHooksEditPost response for editing packagist hook -func PackagistHooksEditPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.NewPackagistHookForm) - ctx.Data["Title"] = ctx.Tr("repo.settings") - ctx.Data["PageIsSettingsHooks"] = true - ctx.Data["PageIsSettingsHooksEdit"] = true - - orCtx, w := checkWebhook(ctx) - if ctx.Written() { - return - } - ctx.Data["Webhook"] = w - - if ctx.HasError() { - ctx.HTML(http.StatusOK, orCtx.NewTemplate) - return - } - - meta, err := json.Marshal(&webhook_service.PackagistMeta{ - Username: form.Username, - APIToken: form.APIToken, - PackageURL: form.PackageURL, - }) - if err != nil { - ctx.ServerError("Marshal", err) - return - } - - w.Meta = string(meta) - w.URL = fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)) - w.HookEvent = ParseHookEvent(form.WebhookForm) - w.IsActive = form.Active - if err := w.UpdateEvent(); err != nil { - ctx.ServerError("UpdateEvent", err) - return - } else if err := webhook.UpdateWebhook(w); err != nil { - ctx.ServerError("UpdateWebhook", err) - return - } - - ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) - ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) -} - // TestWebhook test if web hook is work fine func TestWebhook(ctx *context.Context) { hookID := ctx.ParamsInt64(":id") @@ -950,10 +666,12 @@ func TestWebhook(ctx *context.Context) { }, } + commitID := commit.ID.String() p := &api.PushPayload{ Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, - Before: commit.ID.String(), - After: commit.ID.String(), + Before: commitID, + After: commitID, + CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID), Commits: []*api.PayloadCommit{apiCommit}, HeadCommit: apiCommit, Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone), diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 4cd5856ea..0f349547c 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -15,8 +15,8 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -164,7 +165,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { } wikiName, err := wiki_service.FilenameToName(entry.Name()) if err != nil { - if models.IsErrWikiInvalidFileName(err) { + if repo_model.IsErrWikiInvalidFileName(err) { continue } if wikiRepo != nil { @@ -588,7 +589,7 @@ func WikiPages(ctx *context.Context) { } wikiName, err := wiki_service.FilenameToName(entry.Name()) if err != nil { - if models.IsErrWikiInvalidFileName(err) { + if repo_model.IsErrWikiInvalidFileName(err) { continue } ctx.ServerError("WikiFilenameToName", err) @@ -693,10 +694,10 @@ func NewWikiPost(ctx *context.Context) { } if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.Content, form.Message); err != nil { - if models.IsErrWikiReservedName(err) { + if repo_model.IsErrWikiReservedName(err) { ctx.Data["Err_Title"] = true ctx.RenderWithErr(ctx.Tr("repo.wiki.reserved_page", wikiName), tplWikiNew, &form) - } else if models.IsErrWikiAlreadyExist(err) { + } else if repo_model.IsErrWikiAlreadyExist(err) { ctx.Data["Err_Title"] = true ctx.RenderWithErr(ctx.Tr("repo.wiki.page_already_exists"), tplWikiNew, &form) } else { @@ -705,6 +706,8 @@ func NewWikiPost(ctx *context.Context) { return } + notification.NotifyNewWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName, form.Message) + ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(wikiName)) } @@ -747,6 +750,8 @@ func EditWikiPost(ctx *context.Context) { return } + notification.NotifyEditWikiPage(ctx.Doer, ctx.Repo.Repository, newWikiName, form.Message) + ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(newWikiName)) } @@ -762,6 +767,8 @@ func DeleteWikiPagePost(ctx *context.Context) { return } + notification.NotifyDeleteWikiPage(ctx.Doer, ctx.Repo.Repository, wikiName) + ctx.JSON(http.StatusOK, map[string]interface{}{ "redirect": ctx.Repo.RepoLink + "/wiki/", }) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index f28a68405..837caedc8 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -14,7 +14,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" @@ -56,7 +56,7 @@ func getDashboardContextUser(ctx *context.Context) *user_model.User { } ctx.Data["ContextUser"] = ctxUser - orgs, err := models.GetUserOrgsList(ctx.Doer) + orgs, err := organization.GetUserOrgsList(ctx.Doer) if err != nil { ctx.ServerError("GetUserOrgsList", err) return nil @@ -91,7 +91,7 @@ func Dashboard(ctx *context.Context) { } if setting.Service.EnableUserHeatmap { - data, err := models.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.Doer) + data, err := activities_model.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.Doer) if err != nil { ctx.ServerError("GetUserHeatmapDataByUserTeam", err) return @@ -100,7 +100,7 @@ func Dashboard(ctx *context.Context) { } var err error - ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{ + ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctxUser, RequestedTeam: ctx.Org.Team, Actor: ctx.Doer, @@ -301,6 +301,7 @@ func Pulls(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("pull_requests") ctx.Data["PageIsPulls"] = true + ctx.Data["SingleRepoAction"] = "pull" buildIssueOverview(ctx, unit.TypePullRequests) } @@ -314,6 +315,7 @@ func Issues(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("issues") ctx.Data["PageIsIssues"] = true + ctx.Data["SingleRepoAction"] = "issue" buildIssueOverview(ctx, unit.TypeIssues) } diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 9e658bcb1..5e8142cec 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -12,7 +12,7 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" @@ -36,7 +36,7 @@ func GetNotificationCount(c *context.Context) { } c.Data["NotificationUnreadCount"] = func() int64 { - count, err := models.GetNotificationCount(c, c.Doer, models.NotificationStatusUnread) + count, err := activities_model.GetNotificationCount(c, c.Doer, activities_model.NotificationStatusUnread) if err != nil { if err != goctx.Canceled { log.Error("Unable to GetNotificationCount for user:%-v: %v", c.Doer, err) @@ -65,7 +65,7 @@ func Notifications(c *context.Context) { func getNotifications(c *context.Context) { var ( keyword = c.FormTrim("q") - status models.NotificationStatus + status activities_model.NotificationStatus page = c.FormInt("page") perPage = c.FormInt("perPage") ) @@ -78,12 +78,12 @@ func getNotifications(c *context.Context) { switch keyword { case "read": - status = models.NotificationStatusRead + status = activities_model.NotificationStatusRead default: - status = models.NotificationStatusUnread + status = activities_model.NotificationStatusUnread } - total, err := models.GetNotificationCount(c, c.Doer, status) + total, err := activities_model.GetNotificationCount(c, c.Doer, status) if err != nil { c.ServerError("ErrGetNotificationCount", err) return @@ -96,8 +96,8 @@ func getNotifications(c *context.Context) { return } - statuses := []models.NotificationStatus{status, models.NotificationStatusPinned} - notifications, err := models.NotificationsForUser(c, c.Doer, statuses, page, perPage) + statuses := []activities_model.NotificationStatus{status, activities_model.NotificationStatusPinned} + notifications, err := activities_model.NotificationsForUser(c, c.Doer, statuses, page, perPage) if err != nil { c.ServerError("ErrNotificationsForUser", err) return @@ -151,22 +151,22 @@ func NotificationStatusPost(c *context.Context) { var ( notificationID = c.FormInt64("notification_id") statusStr = c.FormString("status") - status models.NotificationStatus + status activities_model.NotificationStatus ) switch statusStr { case "read": - status = models.NotificationStatusRead + status = activities_model.NotificationStatusRead case "unread": - status = models.NotificationStatusUnread + status = activities_model.NotificationStatusUnread case "pinned": - status = models.NotificationStatusPinned + status = activities_model.NotificationStatusPinned default: c.ServerError("InvalidNotificationStatus", errors.New("Invalid notification status")) return } - if _, err := models.SetNotificationStatus(notificationID, c.Doer, status); err != nil { + if _, err := activities_model.SetNotificationStatus(notificationID, c.Doer, status); err != nil { c.ServerError("SetNotificationStatus", err) return } @@ -188,7 +188,7 @@ func NotificationStatusPost(c *context.Context) { // NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read func NotificationPurgePost(c *context.Context) { - err := models.UpdateNotificationStatuses(c.Doer, models.NotificationStatusUnread, models.NotificationStatusRead) + err := activities_model.UpdateNotificationStatuses(c.Doer, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead) if err != nil { c.ServerError("ErrUpdateNotificationStatuses", err) return @@ -199,5 +199,5 @@ func NotificationPurgePost(c *context.Context) { // NewAvailable returns the notification counts func NewAvailable(ctx *context.Context) { - ctx.JSON(http.StatusOK, structs.NotificationCount{New: models.CountUnread(ctx, ctx.Doer.ID)}) + ctx.JSON(http.StatusOK, structs.NotificationCount{New: activities_model.CountUnread(ctx, ctx.Doer.ID)}) } diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 59aaf07ff..20d8e32d2 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -393,5 +393,5 @@ func DownloadPackageFile(ctx *context.Context) { } defer s.Close() - ctx.ServeStream(s, pf.Name) + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index c804be3c5..a3452fd69 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -10,7 +10,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" project_model "code.gitea.io/gitea/models/project" @@ -69,7 +69,7 @@ func Profile(ctx *context.Context) { ctx.Data["IsFollowing"] = isFollowing if setting.Service.EnableUserHeatmap { - data, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) + data, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) if err != nil { ctx.ServerError("GetUserHeatmapDataByUser", err) return @@ -188,7 +188,7 @@ func Profile(ctx *context.Context) { total = int(count) case "activity": - ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{ + ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: showPrivate, diff --git a/routers/web/user/setting/adopt.go b/routers/web/user/setting/adopt.go index c7139f8bb..a92aa6e98 100644 --- a/routers/web/user/setting/adopt.go +++ b/routers/web/user/setting/adopt.go @@ -7,10 +7,10 @@ package setting import ( "path/filepath" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" repo_service "code.gitea.io/gitea/services/repository" @@ -46,7 +46,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) { if has || !isDir { // Fallthrough to failure mode } else if action == "adopt" && allowAdopt { - if _, err := repo_service.AdoptRepository(ctxUser, ctxUser, models.CreateRepoOptions{ + if _, err := repo_service.AdoptRepository(ctxUser, ctxUser, repo_module.CreateRepoOptions{ Name: dir, IsPrivate: true, }); err != nil { diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go index 4ffec4780..e9572a07a 100644 --- a/routers/web/user/setting/applications.go +++ b/routers/web/user/setting/applications.go @@ -8,8 +8,7 @@ package setting import ( "net/http" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/auth" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -44,12 +43,12 @@ func ApplicationsPost(ctx *context.Context) { return } - t := &models.AccessToken{ + t := &auth_model.AccessToken{ UID: ctx.Doer.ID, Name: form.Name, } - exist, err := models.AccessTokenByNameExists(t) + exist, err := auth_model.AccessTokenByNameExists(t) if err != nil { ctx.ServerError("AccessTokenByNameExists", err) return @@ -60,7 +59,7 @@ func ApplicationsPost(ctx *context.Context) { return } - if err := models.NewAccessToken(t); err != nil { + if err := auth_model.NewAccessToken(t); err != nil { ctx.ServerError("NewAccessToken", err) return } @@ -73,7 +72,7 @@ func ApplicationsPost(ctx *context.Context) { // DeleteApplication response for delete user access token func DeleteApplication(ctx *context.Context) { - if err := models.DeleteAccessTokenByID(ctx.FormInt64("id"), ctx.Doer.ID); err != nil { + if err := auth_model.DeleteAccessTokenByID(ctx.FormInt64("id"), ctx.Doer.ID); err != nil { ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("settings.delete_token_success")) @@ -85,7 +84,7 @@ func DeleteApplication(ctx *context.Context) { } func loadApplicationsData(ctx *context.Context) { - tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.Doer.ID}) + tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID}) if err != nil { ctx.ServerError("ListAccessTokens", err) return @@ -93,12 +92,12 @@ func loadApplicationsData(ctx *context.Context) { ctx.Data["Tokens"] = tokens ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable if setting.OAuth2.Enable { - ctx.Data["Applications"], err = auth.GetOAuth2ApplicationsByUserID(ctx, ctx.Doer.ID) + ctx.Data["Applications"], err = auth_model.GetOAuth2ApplicationsByUserID(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("GetOAuth2ApplicationsByUserID", err) return } - ctx.Data["Grants"], err = auth.GetOAuth2GrantsByUserID(ctx, ctx.Doer.ID) + ctx.Data["Grants"], err = auth_model.GetOAuth2GrantsByUserID(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("GetOAuth2GrantsByUserID", err) return diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go index 218cf57ab..57ea24eeb 100644 --- a/routers/web/user/setting/security/security.go +++ b/routers/web/user/setting/security/security.go @@ -8,8 +8,7 @@ package security import ( "net/http" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/auth" + auth_model "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -56,21 +55,21 @@ func DeleteAccountLink(ctx *context.Context) { } func loadSecurityData(ctx *context.Context) { - enrolled, err := auth.HasTwoFactorByUID(ctx.Doer.ID) + enrolled, err := auth_model.HasTwoFactorByUID(ctx.Doer.ID) if err != nil { ctx.ServerError("SettingsTwoFactor", err) return } ctx.Data["TOTPEnrolled"] = enrolled - credentials, err := auth.GetWebAuthnCredentialsByUID(ctx.Doer.ID) + credentials, err := auth_model.GetWebAuthnCredentialsByUID(ctx.Doer.ID) if err != nil { ctx.ServerError("GetWebAuthnCredentialsByUID", err) return } ctx.Data["WebAuthnCredentials"] = credentials - tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.Doer.ID}) + tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID}) if err != nil { ctx.ServerError("ListAccessTokens", err) return @@ -84,9 +83,9 @@ func loadSecurityData(ctx *context.Context) { } // map the provider display name with the AuthSource - sources := make(map[*auth.Source]string) + sources := make(map[*auth_model.Source]string) for _, externalAccount := range accountLinks { - if authSource, err := auth.GetSourceByID(externalAccount.LoginSourceID); err == nil { + if authSource, err := auth_model.GetSourceByID(externalAccount.LoginSourceID); err == nil { var providerDisplayName string type DisplayNamed interface { diff --git a/routers/web/user/task.go b/routers/web/user/task.go index fd561cdd4..7f5ef792a 100644 --- a/routers/web/user/task.go +++ b/routers/web/user/task.go @@ -8,16 +8,16 @@ import ( "net/http" "strconv" - "code.gitea.io/gitea/models" + admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" ) // TaskStatus returns task's status func TaskStatus(ctx *context.Context) { - task, opts, err := models.GetMigratingTaskByID(ctx.ParamsInt64("task"), ctx.Doer.ID) + task, opts, err := admin_model.GetMigratingTaskByID(ctx.ParamsInt64("task"), ctx.Doer.ID) if err != nil { - if models.IsErrTaskDoesNotExist(err) { + if admin_model.IsErrTaskDoesNotExist(err) { ctx.JSON(http.StatusNotFound, map[string]interface{}{ "error": "task `" + strconv.FormatInt(ctx.ParamsInt64("task"), 10) + "` does not exist", }) @@ -33,9 +33,9 @@ func TaskStatus(ctx *context.Context) { if task.Message != "" && task.Message[0] == '{' { // assume message is actually a translatable string - var translatableMessage models.TranslatableMessage + var translatableMessage admin_model.TranslatableMessage if err := json.Unmarshal([]byte(message), &translatableMessage); err != nil { - translatableMessage = models.TranslatableMessage{ + translatableMessage = admin_model.TranslatableMessage{ Format: "migrate.migrating_failed.error", Args: []interface{}{task.Message}, } diff --git a/routers/web/web.go b/routers/web/web.go index 6462da91f..78c00b77e 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/routing" @@ -98,7 +99,7 @@ func buildAuthGroup() *auth_service.Group { } // Routes returns all web routes -func Routes() *web.Route { +func Routes(ctx gocontext.Context) *web.Route { routes := web.NewRoute() routes.Use(web.WrapWithPrefix(public.AssetsURLPathPrefix, public.AssetsHandlerFunc(&public.Options{ @@ -120,7 +121,9 @@ func Routes() *web.Route { }) routes.Use(sessioner) - routes.Use(Recovery()) + ctx, _ = templates.HTMLRenderer(ctx) + + routes.Use(Recovery(ctx)) // We use r.Route here over r.Use because this prevents requests that are not for avatars having to go through this additional handler routes.Route("/avatars/*", "GET, HEAD", storageHandler(setting.Avatar.Storage, "avatars", storage.Avatars)) @@ -193,10 +196,10 @@ func Routes() *web.Route { routes.Get("/api/healthz", healthcheck.Check) // Removed: toolbox.Toolboxer middleware will provide debug information which seems unnecessary - common = append(common, context.Contexter()) + common = append(common, context.Contexter(ctx)) group := buildAuthGroup() - if err := group.Init(); err != nil { + if err := group.Init(ctx); err != nil { log.Error("Could not initialize '%s' auth method, error: %s", group.Name(), err) } @@ -526,7 +529,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) @@ -679,7 +682,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) @@ -801,7 +804,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/test", repo.TestWebhook) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) - m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.WebHooksEditPost) + m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Post("/discord/{id}", bindIgnErr(forms.NewDiscordHookForm{}), repo.DiscordHooksEditPost) diff --git a/services/auth/basic.go b/services/auth/basic.go index 1869662e9..9b32ad29a 100644 --- a/services/auth/basic.go +++ b/services/auth/basic.go @@ -9,7 +9,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" + auth_model "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" @@ -85,7 +85,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore return u } - token, err := models.GetAccessTokenBySHA(authToken) + token, err := auth_model.GetAccessTokenBySHA(authToken) if err == nil { log.Trace("Basic Authorization: Valid AccessToken for user[%d]", uid) u, err := user_model.GetUserByID(token.UID) @@ -95,13 +95,13 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore } token.UpdatedUnix = timeutil.TimeStampNow() - if err = models.UpdateAccessToken(token); err != nil { + if err = auth_model.UpdateAccessToken(token); err != nil { log.Error("UpdateAccessToken: %v", err) } store.GetData()["IsApiToken"] = true return u - } else if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) { + } else if !auth_model.IsErrAccessTokenNotExist(err) && !auth_model.IsErrAccessTokenEmpty(err) { log.Error("GetAccessTokenBySha: %v", err) } diff --git a/services/auth/group.go b/services/auth/group.go index 0f40e1a76..bbafe64b4 100644 --- a/services/auth/group.go +++ b/services/auth/group.go @@ -5,6 +5,7 @@ package auth import ( + "context" "net/http" "reflect" "strings" @@ -51,14 +52,14 @@ func (b *Group) Name() string { } // Init does nothing as the Basic implementation does not need to allocate any resources -func (b *Group) Init() error { +func (b *Group) Init(ctx context.Context) error { for _, method := range b.methods { initializable, ok := method.(Initializable) if !ok { continue } - if err := initializable.Init(); err != nil { + if err := initializable.Init(ctx); err != nil { return err } } diff --git a/services/auth/interface.go b/services/auth/interface.go index a05ece207..ecc9ad2ca 100644 --- a/services/auth/interface.go +++ b/services/auth/interface.go @@ -34,7 +34,7 @@ type Method interface { type Initializable interface { // Init should be called exactly once before using any of the other methods, // in order to allow the plugin to allocate necessary resources - Init() error + Init(ctx context.Context) error } // Named represents a named thing diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go index 68638a080..8f038d610 100644 --- a/services/auth/oauth2.go +++ b/services/auth/oauth2.go @@ -10,8 +10,7 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/auth" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -37,8 +36,8 @@ func CheckOAuthAccessToken(accessToken string) int64 { log.Trace("oauth2.ParseToken: %v", err) return 0 } - var grant *auth.OAuth2Grant - if grant, err = auth.GetOAuth2GrantByID(db.DefaultContext, token.GrantID); err != nil || grant == nil { + var grant *auth_model.OAuth2Grant + if grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, token.GrantID); err != nil || grant == nil { return 0 } if token.Type != oauth2.TypeAccessToken { @@ -91,15 +90,15 @@ func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 { } return uid } - t, err := models.GetAccessTokenBySHA(tokenSHA) + t, err := auth_model.GetAccessTokenBySHA(tokenSHA) if err != nil { - if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) { + if !auth_model.IsErrAccessTokenNotExist(err) && !auth_model.IsErrAccessTokenEmpty(err) { log.Error("GetAccessTokenBySHA: %v", err) } return 0 } t.UpdatedUnix = timeutil.TimeStampNow() - if err = models.UpdateAccessToken(t); err != nil { + if err = auth_model.UpdateAccessToken(t); err != nil { log.Error("UpdateAccessToken: %v", err) } store.GetData()["IsApiToken"] = true diff --git a/services/auth/sspi_windows.go b/services/auth/sspi_windows.go index 7e31378b6..757d596c4 100644 --- a/services/auth/sspi_windows.go +++ b/services/auth/sspi_windows.go @@ -5,6 +5,7 @@ package auth import ( + "context" "errors" "net/http" "strings" @@ -52,21 +53,14 @@ type SSPI struct { } // Init creates a new global websspi.Authenticator object -func (s *SSPI) Init() error { +func (s *SSPI) Init(ctx context.Context) error { config := websspi.NewConfig() var err error sspiAuth, err = websspi.New(config) if err != nil { return err } - s.rnd = render.New(render.Options{ - Extensions: []string{".tmpl"}, - Directory: "templates", - Funcs: templates.NewFuncMap(), - Asset: templates.GetAsset, - AssetNames: templates.GetAssetNames, - IsDevelopment: !setting.IsProd, - }) + _, s.rnd = templates.HTMLRenderer(ctx) return nil } diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go index 41bd5c442..c3455ec32 100644 --- a/services/cron/tasks_extended.go +++ b/services/cron/tasks_extended.go @@ -8,7 +8,7 @@ import ( "context" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/admin" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" @@ -134,7 +134,7 @@ func registerDeleteOldActions() { OlderThan: 365 * 24 * time.Hour, }, func(ctx context.Context, _ *user_model.User, config Config) error { olderThanConfig := config.(*OlderThanConfig) - return models.DeleteOldActions(olderThanConfig.OlderThan) + return activities_model.DeleteOldActions(olderThanConfig.OlderThan) }) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 7a4a2123e..4eb20d297 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -215,12 +215,12 @@ func (f *ProtectBranchForm) Validate(req *http.Request, errs binding.Errors) bin return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// __ __ ___. .__ .__ __ -// / \ / \ ____\_ |__ | |__ | |__ ____ | | __ -// \ \/\/ // __ \| __ \| | \| | \ / _ \| |/ / -// \ /\ ___/| \_\ \ Y \ Y ( <_> ) < -// \__/\ / \___ >___ /___| /___| /\____/|__|_ \ -// \/ \/ \/ \/ \/ \/ +// __ __ ___. .__ __ +// / \ / \ ____\_ |__ | |__ ____ ____ | | __ +// \ \/\/ // __ \| __ \| | \ / _ \ / _ \| |/ / +// \ /\ ___/| \_\ \ Y ( <_> | <_> ) < +// \__/\ / \___ >___ /___| /\____/ \____/|__|_ \ +// \/ \/ \/ \/ \/ // WebhookForm form for changing web hook type WebhookForm struct { @@ -242,6 +242,7 @@ type WebhookForm struct { PullRequestComment bool PullRequestReview bool PullRequestSync bool + Wiki bool Repository bool Package bool Active bool diff --git a/services/issue/commit.go b/services/issue/commit.go index 1053a8116..0d04de81b 100644 --- a/services/issue/commit.go +++ b/services/issue/commit.go @@ -13,12 +13,12 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/repository" ) @@ -119,8 +119,13 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm // issue is from another repo if len(ref.Owner) > 0 && len(ref.Name) > 0 { - refRepo, err = models.GetRepositoryFromMatch(ref.Owner, ref.Name) + refRepo, err = repo_model.GetRepositoryByOwnerAndName(ref.Owner, ref.Name) if err != nil { + if repo_model.IsErrRepoNotExist(err) { + log.Warn("Repository referenced in commit but does not exist: %v", err) + } else { + log.Error("repo_model.GetRepositoryByOwnerAndName: %v", err) + } continue } } else { diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go index f9ad0302f..8469bf1ac 100644 --- a/services/issue/commit_test.go +++ b/services/issue/commit_test.go @@ -7,7 +7,7 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -64,7 +64,7 @@ func TestUpdateIssuesCommit(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) // Test that push to a non-default branch closes no issue. pushCommits = []*repository.PushCommit{ @@ -91,7 +91,7 @@ func TestUpdateIssuesCommit(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) pushCommits = []*repository.PushCommit{ { @@ -117,7 +117,7 @@ func TestUpdateIssuesCommit(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } func TestUpdateIssuesCommit_Colon(t *testing.T) { @@ -142,7 +142,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } func TestUpdateIssuesCommit_Issue5957(t *testing.T) { @@ -176,7 +176,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { @@ -211,7 +211,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { @@ -246,7 +246,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { @@ -297,5 +297,5 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, commentBean2) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - unittest.CheckConsistencyFor(t, &models.Action{}) + unittest.CheckConsistencyFor(t, &activities_model.Action{}) } diff --git a/services/issue/issue.go b/services/issue/issue.go index 7131829b0..bbd027879 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -7,7 +7,7 @@ package issue import ( "fmt" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" @@ -224,7 +224,7 @@ func deleteIssue(issue *issues_model.Issue) error { return err } - if err := models.DeleteIssueActions(ctx, issue.RepoID, issue.ID); err != nil { + if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID); err != nil { return err } @@ -245,7 +245,7 @@ func deleteIssue(issue *issues_model.Issue) error { &issues_model.IssueDependency{}, &issues_model.IssueAssignees{}, &issues_model.IssueUser{}, - &models.Notification{}, + &activities_model.Notification{}, &issues_model.Reaction{}, &issues_model.IssueWatch{}, &issues_model.Stopwatch{}, diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 738a207ce..a5bfa496f 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -17,7 +17,7 @@ import ( texttmpl "text/template" "time" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -302,7 +302,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient // Make sure to compose independent messages to avoid leaking user emails msgID := createReference(ctx.Issue, ctx.Comment, ctx.ActionType) - reference := createReference(ctx.Issue, nil, models.ActionType(0)) + reference := createReference(ctx.Issue, nil, activities_model.ActionType(0)) msgs := make([]*Message, 0, len(recipients)) for _, recipient := range recipients { @@ -323,7 +323,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient return msgs, nil } -func createReference(issue *issues_model.Issue, comment *issues_model.Comment, actionType models.ActionType) string { +func createReference(issue *issues_model.Issue, comment *issues_model.Comment, actionType activities_model.ActionType) string { var path string if issue.IsPull { path = "pulls" @@ -336,13 +336,13 @@ func createReference(issue *issues_model.Issue, comment *issues_model.Comment, a extra = fmt.Sprintf("/comment/%d", comment.ID) } else { switch actionType { - case models.ActionCloseIssue, models.ActionClosePullRequest: + case activities_model.ActionCloseIssue, activities_model.ActionClosePullRequest: extra = fmt.Sprintf("/close/%d", time.Now().UnixNano()/1e6) - case models.ActionReopenIssue, models.ActionReopenPullRequest: + case activities_model.ActionReopenIssue, activities_model.ActionReopenPullRequest: extra = fmt.Sprintf("/reopen/%d", time.Now().UnixNano()/1e6) - case models.ActionMergePullRequest: + case activities_model.ActionMergePullRequest: extra = fmt.Sprintf("/merge/%d", time.Now().UnixNano()/1e6) - case models.ActionPullRequestReadyForReview: + case activities_model.ActionPullRequestReadyForReview: extra = fmt.Sprintf("/ready/%d", time.Now().UnixNano()/1e6) } } @@ -420,7 +420,7 @@ func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, con Context: context.TODO(), // TODO: use a correct context Issue: issue, Doer: doer, - ActionType: models.ActionType(0), + ActionType: activities_model.ActionType(0), Content: content, Comment: comment, }, lang, tos, false, "issue assigned") @@ -433,8 +433,8 @@ func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, con } // actionToTemplate returns the type and name of the action facing the user -// (slightly different from models.ActionType) and the name of the template to use (based on availability) -func actionToTemplate(issue *issues_model.Issue, actionType models.ActionType, +// (slightly different from activities_model.ActionType) and the name of the template to use (based on availability) +func actionToTemplate(issue *issues_model.Issue, actionType activities_model.ActionType, commentType issues_model.CommentType, reviewType issues_model.ReviewType, ) (typeName, name, template string) { if issue.IsPull { @@ -443,19 +443,19 @@ func actionToTemplate(issue *issues_model.Issue, actionType models.ActionType, typeName = "issue" } switch actionType { - case models.ActionCreateIssue, models.ActionCreatePullRequest: + case activities_model.ActionCreateIssue, activities_model.ActionCreatePullRequest: name = "new" - case models.ActionCommentIssue, models.ActionCommentPull: + case activities_model.ActionCommentIssue, activities_model.ActionCommentPull: name = "comment" - case models.ActionCloseIssue, models.ActionClosePullRequest: + case activities_model.ActionCloseIssue, activities_model.ActionClosePullRequest: name = "close" - case models.ActionReopenIssue, models.ActionReopenPullRequest: + case activities_model.ActionReopenIssue, activities_model.ActionReopenPullRequest: name = "reopen" - case models.ActionMergePullRequest: + case activities_model.ActionMergePullRequest: name = "merge" - case models.ActionPullReviewDismissed: + case activities_model.ActionPullReviewDismissed: name = "review_dismissed" - case models.ActionPullRequestReadyForReview: + case activities_model.ActionPullRequestReadyForReview: name = "ready_for_review" default: switch commentType { diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go index 95d11ae8a..2dab673b4 100644 --- a/services/mailer/mail_comment.go +++ b/services/mailer/mail_comment.go @@ -7,7 +7,7 @@ package mailer import ( "context" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -15,7 +15,7 @@ import ( ) // MailParticipantsComment sends new comment emails to repository watchers and mentioned people. -func MailParticipantsComment(ctx context.Context, c *issues_model.Comment, opType models.ActionType, issue *issues_model.Issue, mentions []*user_model.User) error { +func MailParticipantsComment(ctx context.Context, c *issues_model.Comment, opType activities_model.ActionType, issue *issues_model.Issue, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil @@ -53,7 +53,7 @@ func MailMentionsComment(ctx context.Context, pr *issues_model.PullRequest, c *i Context: ctx, Issue: pr.Issue, Doer: c.Poster, - ActionType: models.ActionCommentPull, + ActionType: activities_model.ActionCommentPull, Content: c.Content, Comment: c, }, mentions, visited, true); err != nil { diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index b4827e83a..ec6ddcf14 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -8,8 +8,9 @@ import ( "context" "fmt" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -25,7 +26,7 @@ type mailCommentContext struct { context.Context Issue *issues_model.Issue Doer *user_model.User - ActionType models.ActionType + ActionType activities_model.ActionType Content string Comment *issues_model.Comment } @@ -80,7 +81,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo // =========== Repo watchers =========== // Make repo watchers last, since it's likely the list with the most users - if !(ctx.Issue.IsPull && ctx.Issue.PullRequest.IsWorkInProgress() && ctx.ActionType != models.ActionCreatePullRequest) { + if !(ctx.Issue.IsPull && ctx.Issue.PullRequest.IsWorkInProgress() && ctx.ActionType != activities_model.ActionCreatePullRequest) { ids, err = repo_model.GetRepoWatchersIDs(ctx, ctx.Issue.RepoID) if err != nil { return fmt.Errorf("GetRepoWatchersIDs(%d): %v", ctx.Issue.RepoID, err) @@ -149,7 +150,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi visited[user.ID] = true // test if this user is allowed to see the issue/pull - if !models.CheckRepoUnitUser(ctx, ctx.Issue.Repo, user, checkUnit) { + if !access_model.CheckRepoUnitUser(ctx, ctx.Issue.Repo, user, checkUnit) { continue } @@ -175,16 +176,16 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi // MailParticipants sends new issue thread created emails to repository watchers // and mentioned people. -func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType models.ActionType, mentions []*user_model.User) error { +func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType activities_model.ActionType, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil } content := issue.Content - if opType == models.ActionCloseIssue || opType == models.ActionClosePullRequest || - opType == models.ActionReopenIssue || opType == models.ActionReopenPullRequest || - opType == models.ActionMergePullRequest { + if opType == activities_model.ActionCloseIssue || opType == activities_model.ActionClosePullRequest || + opType == activities_model.ActionReopenIssue || opType == activities_model.ActionReopenPullRequest || + opType == activities_model.ActionMergePullRequest { content = "" } if err := mailIssueCommentToParticipants( diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index dd9f78612..7c44f9392 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -8,7 +8,6 @@ import ( "bytes" "context" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -25,7 +24,7 @@ const ( ) // MailNewRelease send new release notify to all all repo watchers. -func MailNewRelease(ctx context.Context, rel *models.Release) { +func MailNewRelease(ctx context.Context, rel *repo_model.Release) { if setting.MailService == nil { // No mail service configured return @@ -55,7 +54,7 @@ func MailNewRelease(ctx context.Context, rel *models.Release) { } } -func mailNewRelease(ctx context.Context, lang string, tos []string, rel *models.Release) { +func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_model.Release) { locale := translation.NewLocale(lang) var err error diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 4302b2c74..acb1f6996 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -13,7 +13,7 @@ import ( "testing" texttmpl "text/template" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -73,7 +73,7 @@ func TestComposeIssueCommentMessage(t *testing.T) { recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue, + Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue, Content: "test body", Comment: comment, }, "en-US", recipients, false, "issue comment") assert.NoError(t, err) @@ -102,7 +102,7 @@ func TestComposeIssueMessage(t *testing.T) { recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue, + Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, Content: "test body", }, "en-US", recipients, false, "issue create") assert.NoError(t, err) @@ -147,14 +147,14 @@ func TestTemplateSelection(t *testing.T) { msg := testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue, + Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, Content: "test body", }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/new/subject", "issue/new/body") msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue, + Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/default/subject", "issue/default/body") @@ -163,14 +163,14 @@ func TestTemplateSelection(t *testing.T) { comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}) msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: pull, Doer: doer, ActionType: models.ActionCommentPull, + Issue: pull, Doer: doer, ActionType: activities_model.ActionCommentPull, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") expect(t, msg, "pull/comment/subject", "pull/comment/body") msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context - Issue: issue, Doer: doer, ActionType: models.ActionCloseIssue, + Issue: issue, Doer: doer, ActionType: activities_model.ActionCloseIssue, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "issue/close/body") @@ -181,7 +181,7 @@ func TestTemplateServices(t *testing.T) { assert.NoError(t, issue.LoadRepo(db.DefaultContext)) expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User, - actionType models.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string, + actionType activities_model.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string, ) { subjectTemplates = texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject)) bodyTemplates = template.Must(template.New("issue/default").Parse(tplBody)) @@ -202,19 +202,19 @@ func TestTemplateServices(t *testing.T) { assert.Contains(t, wholemsg, "\r\n"+expBody+"\r\n") } - expect(t, issue, comment, doer, models.ActionCommentIssue, false, + expect(t, issue, comment, doer, activities_model.ActionCommentIssue, false, "{{.SubjectPrefix}}[{{.Repo}}]: @{{.Doer.Name}} commented on #{{.Issue.Index}} - {{.Issue.Title}}", "//{{.ActionType}},{{.ActionName}},{{if .IsMention}}norender{{end}}//", "Re: [user2/repo1]: @user2 commented on #1 - issue1", "//issue,comment,//") - expect(t, issue, comment, doer, models.ActionCommentIssue, true, + expect(t, issue, comment, doer, activities_model.ActionCommentIssue, true, "{{if .IsMention}}must render{{end}}", "//subject is: {{.Subject}}//", "must render", "//subject is: must render//") - expect(t, issue, comment, doer, models.ActionCommentIssue, true, + expect(t, issue, comment, doer, activities_model.ActionCommentIssue, true, "{{.FallbackSubject}}", "//{{.SubjectPrefix}}//", "Re: [user2/repo1] issue1 (#1)", @@ -266,7 +266,7 @@ func Test_createReference(t *testing.T) { type args struct { issue *issues_model.Issue comment *issues_model.Comment - actionType models.ActionType + actionType activities_model.ActionType } tests := []struct { name string @@ -278,7 +278,7 @@ func Test_createReference(t *testing.T) { name: "Open Issue", args: args{ issue: issue, - actionType: models.ActionCreateIssue, + actionType: activities_model.ActionCreateIssue, }, prefix: fmt.Sprintf("%s/issues/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain), }, @@ -286,7 +286,7 @@ func Test_createReference(t *testing.T) { name: "Open Pull", args: args{ issue: pullIssue, - actionType: models.ActionCreatePullRequest, + actionType: activities_model.ActionCreatePullRequest, }, prefix: fmt.Sprintf("%s/pulls/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain), }, @@ -295,7 +295,7 @@ func Test_createReference(t *testing.T) { args: args{ issue: issue, comment: comment, - actionType: models.ActionCommentIssue, + actionType: activities_model.ActionCommentIssue, }, prefix: fmt.Sprintf("%s/issues/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain), }, @@ -304,7 +304,7 @@ func Test_createReference(t *testing.T) { args: args{ issue: pullIssue, comment: comment, - actionType: models.ActionCommentPull, + actionType: activities_model.ActionCommentPull, }, prefix: fmt.Sprintf("%s/pulls/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain), }, @@ -312,7 +312,7 @@ func Test_createReference(t *testing.T) { name: "Close Issue", args: args{ issue: issue, - actionType: models.ActionCloseIssue, + actionType: activities_model.ActionCloseIssue, }, prefix: fmt.Sprintf("%s/issues/%d/close/", issue.Repo.FullName(), issue.Index), }, @@ -320,7 +320,7 @@ func Test_createReference(t *testing.T) { name: "Close Pull", args: args{ issue: pullIssue, - actionType: models.ActionClosePullRequest, + actionType: activities_model.ActionClosePullRequest, }, prefix: fmt.Sprintf("%s/pulls/%d/close/", issue.Repo.FullName(), issue.Index), }, @@ -328,7 +328,7 @@ func Test_createReference(t *testing.T) { name: "Reopen Issue", args: args{ issue: issue, - actionType: models.ActionReopenIssue, + actionType: activities_model.ActionReopenIssue, }, prefix: fmt.Sprintf("%s/issues/%d/reopen/", issue.Repo.FullName(), issue.Index), }, @@ -336,7 +336,7 @@ func Test_createReference(t *testing.T) { name: "Reopen Pull", args: args{ issue: pullIssue, - actionType: models.ActionReopenPullRequest, + actionType: activities_model.ActionReopenPullRequest, }, prefix: fmt.Sprintf("%s/pulls/%d/reopen/", issue.Repo.FullName(), issue.Index), }, @@ -344,7 +344,7 @@ func Test_createReference(t *testing.T) { name: "Merge Pull", args: args{ issue: pullIssue, - actionType: models.ActionMergePullRequest, + actionType: activities_model.ActionMergePullRequest, }, prefix: fmt.Sprintf("%s/pulls/%d/merge/", issue.Repo.FullName(), issue.Index), }, @@ -352,7 +352,7 @@ func Test_createReference(t *testing.T) { name: "Ready Pull", args: args{ issue: pullIssue, - actionType: models.ActionPullRequestReadyForReview, + actionType: activities_model.ActionPullRequestReadyForReview, }, prefix: fmt.Sprintf("%s/pulls/%d/ready/", issue.Repo.FullName(), issue.Index), }, diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index fdbb6e562..1f43c7f82 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -7,6 +7,7 @@ package mailer import ( "bytes" + "context" "crypto/tls" "fmt" "hash/fnv" @@ -348,7 +349,7 @@ var mailQueue queue.Queue var Sender gomail.Sender // NewContext start mail queue service -func NewContext() { +func NewContext(ctx context.Context) { // Need to check if mailQueue is nil because in during reinstall (user had installed // before but switched install lock off), this function will be called again // while mail queue is already processing tasks, and produces a race condition. @@ -381,7 +382,7 @@ func NewContext() { go graceful.GetManager().RunWithShutdownFns(mailQueue.Run) - subjectTemplates, bodyTemplates = templates.Mailer() + subjectTemplates, bodyTemplates = templates.Mailer(ctx) } // SendAsync send mail asynchronously diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go index bb74c0a49..edeb27677 100644 --- a/services/migrations/codebase.go +++ b/services/migrations/codebase.go @@ -107,9 +107,24 @@ func NewCodebaseDownloader(ctx context.Context, projectURL *url.URL, project, re commitMap: make(map[string]string), } + log.Trace("Create Codebase downloader. BaseURL: %s Project: %s RepoName: %s", baseURL, project, repoName) return downloader } +// String implements Stringer +func (d *CodebaseDownloader) String() string { + return fmt.Sprintf("migration from codebase server %s %s/%s", d.baseURL, d.project, d.repoName) +} + +// ColorFormat provides a basic color format for a GogsDownloader +func (d *CodebaseDownloader) ColorFormat(s fmt.State) { + if d == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from codebase server %s %s/%s", d.baseURL, d.project, d.repoName) +} + // FormatCloneURL add authentication into remote URLs func (d *CodebaseDownloader) FormatCloneURL(opts base.MigrateOptions, remoteAddr string) (string, error) { return opts.CloneAddr, nil @@ -451,8 +466,8 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq Value int64 `xml:",chardata"` Type string `xml:"type,attr"` } `xml:"id"` - SourceRef string `xml:"source-ref"` - TargetRef string `xml:"target-ref"` + SourceRef string `xml:"source-ref"` // NOTE: from the documentation these are actually just branches NOT full refs + TargetRef string `xml:"target-ref"` // NOTE: from the documentation these are actually just branches NOT full refs Subject string `xml:"subject"` Status string `xml:"status"` UserID struct { @@ -564,6 +579,9 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq Comments: comments[1:], }, }) + + // SECURITY: Ensure that the PR is safe + _ = CheckAndEnsureSafePR(pullRequests[len(pullRequests)-1], d.baseURL.String(), d) } return pullRequests, true, nil diff --git a/services/migrations/common.go b/services/migrations/common.go new file mode 100644 index 000000000..305ae89b2 --- /dev/null +++ b/services/migrations/common.go @@ -0,0 +1,82 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "fmt" + "strings" + + admin_model "code.gitea.io/gitea/models/admin" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + base "code.gitea.io/gitea/modules/migration" +) + +// WarnAndNotice will log the provided message and send a repository notice +func WarnAndNotice(fmtStr string, args ...interface{}) { + log.Warn(fmtStr, args...) + if err := admin_model.CreateRepositoryNotice(fmt.Sprintf(fmtStr, args...)); err != nil { + log.Error("create repository notice failed: ", err) + } +} + +func hasBaseURL(toCheck, baseURL string) bool { + if len(baseURL) > 0 && baseURL[len(baseURL)-1] != '/' { + baseURL += "/" + } + return strings.HasPrefix(toCheck, baseURL) +} + +// CheckAndEnsureSafePR will check that a given PR is safe to download +func CheckAndEnsureSafePR(pr *base.PullRequest, commonCloneBaseURL string, g base.Downloader) bool { + valid := true + // SECURITY: the patchURL must be checked to have the same baseURL as the current to prevent open redirect + if pr.PatchURL != "" && !hasBaseURL(pr.PatchURL, commonCloneBaseURL) { + // TODO: Should we check that this url has the expected format for a patch url? + WarnAndNotice("PR #%d in %s has invalid PatchURL: %s baseURL: %s", pr.Number, g, pr.PatchURL, commonCloneBaseURL) + pr.PatchURL = "" + valid = false + } + + // SECURITY: the headCloneURL must be checked to have the same baseURL as the current to prevent open redirect + if pr.Head.CloneURL != "" && !hasBaseURL(pr.Head.CloneURL, commonCloneBaseURL) { + // TODO: Should we check that this url has the expected format for a patch url? + WarnAndNotice("PR #%d in %s has invalid HeadCloneURL: %s baseURL: %s", pr.Number, g, pr.Head.CloneURL, commonCloneBaseURL) + pr.Head.CloneURL = "" + valid = false + } + + // SECURITY: SHAs Must be a SHA + if pr.MergeCommitSHA != "" && !git.IsValidSHAPattern(pr.MergeCommitSHA) { + WarnAndNotice("PR #%d in %s has invalid MergeCommitSHA: %s", pr.Number, g, pr.MergeCommitSHA) + pr.MergeCommitSHA = "" + } + if pr.Head.SHA != "" && !git.IsValidSHAPattern(pr.Head.SHA) { + WarnAndNotice("PR #%d in %s has invalid HeadSHA: %s", pr.Number, g, pr.Head.SHA) + pr.Head.SHA = "" + valid = false + } + if pr.Base.SHA != "" && !git.IsValidSHAPattern(pr.Base.SHA) { + WarnAndNotice("PR #%d in %s has invalid BaseSHA: %s", pr.Number, g, pr.Base.SHA) + pr.Base.SHA = "" + valid = false + } + + // SECURITY: Refs must be valid refs or SHAs + if pr.Head.Ref != "" && !git.IsValidRefPattern(pr.Head.Ref) { + WarnAndNotice("PR #%d in %s has invalid HeadRef: %s", pr.Number, g, pr.Head.Ref) + pr.Head.Ref = "" + valid = false + } + if pr.Base.Ref != "" && !git.IsValidRefPattern(pr.Base.Ref) { + WarnAndNotice("PR #%d in %s has invalid BaseRef: %s", pr.Number, g, pr.Base.Ref) + pr.Base.Ref = "" + valid = false + } + + pr.EnsuredSafe = true + + return valid +} diff --git a/services/migrations/dump.go b/services/migrations/dump.go index a9ec45951..188f2775e 100644 --- a/services/migrations/dump.go +++ b/services/migrations/dump.go @@ -12,7 +12,6 @@ import ( "net/http" "net/url" "os" - "path" "path/filepath" "strconv" "strings" @@ -26,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "github.com/google/uuid" "gopkg.in/yaml.v2" ) @@ -47,7 +47,7 @@ type RepositoryDumper struct { reviewFiles map[int64]*os.File gitRepo *git.Repository - prHeadCache map[string]struct{} + prHeadCache map[string]string } // NewRepositoryDumper creates an gitea Uploader @@ -62,7 +62,7 @@ func NewRepositoryDumper(ctx context.Context, baseDir, repoOwner, repoName strin baseDir: baseDir, repoOwner: repoOwner, repoName: repoName, - prHeadCache: make(map[string]struct{}), + prHeadCache: make(map[string]string), commentFiles: make(map[int64]*os.File), reviewFiles: make(map[int64]*os.File), }, nil @@ -296,8 +296,10 @@ func (g *RepositoryDumper) CreateReleases(releases ...*base.Release) error { } for _, asset := range release.Assets { attachLocalPath := filepath.Join(attachDir, asset.Name) - // download attachment + // SECURITY: We cannot check the DownloadURL and DownloadFunc are safe here + // ... we must assume that they are safe and simply download the attachment + // download attachment err := func(attachPath string) error { var rc io.ReadCloser var err error @@ -317,7 +319,7 @@ func (g *RepositoryDumper) CreateReleases(releases ...*base.Release) error { fw, err := os.Create(attachPath) if err != nil { - return fmt.Errorf("Create: %v", err) + return fmt.Errorf("create: %w", err) } defer fw.Close() @@ -385,22 +387,7 @@ func (g *RepositoryDumper) createItems(dir string, itemFiles map[int64]*os.File, } for number, items := range itemsMap { - var err error - itemFile := itemFiles[number] - if itemFile == nil { - itemFile, err = os.Create(filepath.Join(dir, fmt.Sprintf("%d.yml", number))) - if err != nil { - return err - } - itemFiles[number] = itemFile - } - - bs, err := yaml.Marshal(items) - if err != nil { - return err - } - - if _, err := itemFile.Write(bs); err != nil { + if err := g.encodeItems(number, items, dir, itemFiles); err != nil { return err } } @@ -408,6 +395,23 @@ func (g *RepositoryDumper) createItems(dir string, itemFiles map[int64]*os.File, return nil } +func (g *RepositoryDumper) encodeItems(number int64, items []interface{}, dir string, itemFiles map[int64]*os.File) error { + itemFile := itemFiles[number] + if itemFile == nil { + var err error + itemFile, err = os.Create(filepath.Join(dir, fmt.Sprintf("%d.yml", number))) + if err != nil { + return err + } + itemFiles[number] = itemFile + } + + encoder := yaml.NewEncoder(itemFile) + defer encoder.Close() + + return encoder.Encode(items) +} + // CreateComments creates comments of issues func (g *RepositoryDumper) CreateComments(comments ...*base.Comment) error { commentsMap := make(map[int64][]interface{}, len(comments)) @@ -418,102 +422,175 @@ func (g *RepositoryDumper) CreateComments(comments ...*base.Comment) error { return g.createItems(g.commentDir(), g.commentFiles, commentsMap) } -// CreatePullRequests creates pull requests -func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { - for _, pr := range prs { - // download patch file - err := func() error { - u, err := g.setURLToken(pr.PatchURL) - if err != nil { - return err - } - resp, err := http.Get(u) - if err != nil { - return err - } - defer resp.Body.Close() - pullDir := filepath.Join(g.gitPath(), "pulls") - if err = os.MkdirAll(pullDir, os.ModePerm); err != nil { - return err - } - fPath := filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)) - f, err := os.Create(fPath) - if err != nil { - return err - } - defer f.Close() - if _, err = io.Copy(f, resp.Body); err != nil { - return err - } - pr.PatchURL = "git/pulls/" + fmt.Sprintf("%d.patch", pr.Number) - - return nil - }() - if err != nil { - return err - } - - // set head information - pullHead := filepath.Join(g.gitPath(), "refs", "pull", fmt.Sprintf("%d", pr.Number)) - if err := os.MkdirAll(pullHead, os.ModePerm); err != nil { - return err - } - p, err := os.Create(filepath.Join(pullHead, "head")) - if err != nil { - return err - } - _, err = p.WriteString(pr.Head.SHA) - p.Close() - if err != nil { - return err - } - - if pr.IsForkPullRequest() && pr.State != "closed" { - if pr.Head.OwnerName != "" { - remote := pr.Head.OwnerName - _, ok := g.prHeadCache[remote] - if !ok { - // git remote add - // TODO: how to handle private CloneURL? - err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true) - if err != nil { - log.Error("AddRemote failed: %s", err) - } else { - g.prHeadCache[remote] = struct{}{} - ok = true - } - } - - if ok { - _, _, err = git.NewCommand(g.ctx, "fetch", remote, pr.Head.Ref).RunStdString(&git.RunOpts{Dir: g.gitPath()}) - if err != nil { - log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) - } else { - // a new branch name with will be created to as new head branch - ref := path.Join(pr.Head.OwnerName, pr.Head.Ref) - headBranch := filepath.Join(g.gitPath(), "refs", "heads", ref) - if err := os.MkdirAll(filepath.Dir(headBranch), os.ModePerm); err != nil { - return err - } - b, err := os.Create(headBranch) - if err != nil { - return err - } - _, err = b.WriteString(pr.Head.SHA) - b.Close() - if err != nil { - return err - } - pr.Head.Ref = ref - } - } - } - } - // whatever it's a forked repo PR, we have to change head info as the same as the base info - pr.Head.OwnerName = pr.Base.OwnerName - pr.Head.RepoName = pr.Base.RepoName +func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { + // SECURITY: this pr must have been ensured safe + if !pr.EnsuredSafe { + log.Error("PR #%d in %s/%s has not been checked for safety ... We will ignore this.", pr.Number, g.repoOwner, g.repoName) + return fmt.Errorf("unsafe PR #%d", pr.Number) } + // First we download the patch file + err := func() error { + // if the patchURL is empty there is nothing to download + if pr.PatchURL == "" { + return nil + } + + // SECURITY: We will assume that the pr.PatchURL has been checked + // pr.PatchURL maybe a local file - but note EnsureSafe should be asserting that this safe + u, err := g.setURLToken(pr.PatchURL) + if err != nil { + return err + } + + // SECURITY: We will assume that the pr.PatchURL has been checked + // pr.PatchURL maybe a local file - but note EnsureSafe should be asserting that this safe + resp, err := http.Get(u) // TODO: This probably needs to use the downloader as there may be rate limiting issues here + if err != nil { + return err + } + defer resp.Body.Close() + pullDir := filepath.Join(g.gitPath(), "pulls") + if err = os.MkdirAll(pullDir, os.ModePerm); err != nil { + return err + } + fPath := filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)) + f, err := os.Create(fPath) + if err != nil { + return err + } + defer f.Close() + + // TODO: Should there be limits on the size of this file? + if _, err = io.Copy(f, resp.Body); err != nil { + return err + } + pr.PatchURL = "git/pulls/" + fmt.Sprintf("%d.patch", pr.Number) + + return nil + }() + if err != nil { + log.Error("PR #%d in %s/%s unable to download patch: %v", pr.Number, g.repoOwner, g.repoName, err) + return err + } + + isFork := pr.IsForkPullRequest() + + // Even if it's a forked repo PR, we have to change head info as the same as the base info + oldHeadOwnerName := pr.Head.OwnerName + pr.Head.OwnerName, pr.Head.RepoName = pr.Base.OwnerName, pr.Base.RepoName + + if !isFork || pr.State == "closed" { + return nil + } + + // OK we want to fetch the current head as a branch from its CloneURL + + // 1. Is there a head clone URL available? + // 2. Is there a head ref available? + if pr.Head.CloneURL == "" || pr.Head.Ref == "" { + // Set head information if pr.Head.SHA is available + if pr.Head.SHA != "" { + _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref", pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + if err != nil { + log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) + } + } + return nil + } + + // 3. We need to create a remote for this clone url + // ... maybe we already have a name for this remote + remote, ok := g.prHeadCache[pr.Head.CloneURL+":"] + if !ok { + // ... let's try ownername as a reasonable name + remote = oldHeadOwnerName + if !git.IsValidRefPattern(remote) { + // ... let's try something less nice + remote = "head-pr-" + strconv.FormatInt(pr.Number, 10) + } + // ... now add the remote + err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true) + if err != nil { + log.Error("PR #%d in %s/%s AddRemote[%s] failed: %v", pr.Number, g.repoOwner, g.repoName, remote, err) + } else { + g.prHeadCache[pr.Head.CloneURL+":"] = remote + ok = true + } + } + if !ok { + // Set head information if pr.Head.SHA is available + if pr.Head.SHA != "" { + _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref", pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + if err != nil { + log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) + } + } + + return nil + } + + // 4. Check if we already have this ref? + localRef, ok := g.prHeadCache[pr.Head.CloneURL+":"+pr.Head.Ref] + if !ok { + // ... We would normally name this migrated branch as / but we need to ensure that is safe + localRef = git.SanitizeRefPattern(oldHeadOwnerName + "/" + pr.Head.Ref) + + // ... Now we must assert that this does not exist + if g.gitRepo.IsBranchExist(localRef) { + localRef = "head-pr-" + strconv.FormatInt(pr.Number, 10) + "/" + localRef + i := 0 + for g.gitRepo.IsBranchExist(localRef) { + if i > 5 { + // ... We tried, we really tried but this is just a seriously unfriendly repo + return fmt.Errorf("unable to create unique local reference from %s", pr.Head.Ref) + } + // OK just try some uuids! + localRef = git.SanitizeRefPattern("head-pr-" + strconv.FormatInt(pr.Number, 10) + uuid.New().String()) + i++ + } + } + + fetchArg := pr.Head.Ref + ":" + git.BranchPrefix + localRef + if strings.HasPrefix(fetchArg, "-") { + fetchArg = git.BranchPrefix + fetchArg + } + + _, _, err = git.NewCommand(g.ctx, "fetch", "--no-tags", "--", remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + if err != nil { + log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) + // We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR + // (This last step will likely fail but we should try to do as much as we can.) + } else { + // Cache the localRef as the Head.Ref - if we've failed we can always try again. + g.prHeadCache[pr.Head.CloneURL+":"+pr.Head.Ref] = localRef + } + } + + // Set the pr.Head.Ref to the localRef + pr.Head.Ref = localRef + + // 5. Now if pr.Head.SHA == "" we should recover this to the head of this branch + if pr.Head.SHA == "" { + headSha, err := g.gitRepo.GetBranchCommitID(localRef) + if err != nil { + log.Error("unable to get head SHA of local head for PR #%d from %s in %s/%s. Error: %v", pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) + return nil + } + pr.Head.SHA = headSha + } + if pr.Head.SHA != "" { + _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref", pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + if err != nil { + log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) + } + } + + return nil +} + +// CreatePullRequests creates pull requests +func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { var err error if g.pullrequestFile == nil { if err := os.MkdirAll(g.baseDir, os.ModePerm); err != nil { @@ -525,16 +602,22 @@ func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { } } - bs, err := yaml.Marshal(prs) - if err != nil { - return err - } + encoder := yaml.NewEncoder(g.pullrequestFile) + defer encoder.Close() - if _, err := g.pullrequestFile.Write(bs); err != nil { - return err + count := 0 + for i := 0; i < len(prs); i++ { + pr := prs[i] + if err := g.handlePullRequest(pr); err != nil { + log.Error("PR #%d in %s/%s failed - skipping", pr.Number, g.repoOwner, g.repoName, err) + continue + } + prs[count] = pr + count++ } + prs = prs[:count] - return nil + return encoder.Encode(prs) } // CreateReviews create pull request reviews @@ -560,6 +643,10 @@ func (g *RepositoryDumper) Finish() error { // DumpRepository dump repository according MigrateOptions to a local directory func DumpRepository(ctx context.Context, baseDir, ownerName string, opts base.MigrateOptions) error { + doer, err := user_model.GetAdminUser() + if err != nil { + return err + } downloader, err := newDownloader(ctx, ownerName, opts) if err != nil { return err @@ -569,7 +656,7 @@ func DumpRepository(ctx context.Context, baseDir, ownerName string, opts base.Mi return err } - if err := migrateRepository(downloader, uploader, opts, nil); err != nil { + if err := migrateRepository(doer, downloader, uploader, opts, nil); err != nil { if err1 := uploader.Rollback(); err1 != nil { log.Error("rollback failed: %v", err1) } @@ -641,7 +728,7 @@ func RestoreRepository(ctx context.Context, baseDir, ownerName, repoName string, return err } - if err = migrateRepository(downloader, uploader, migrateOpts, nil); err != nil { + if err = migrateRepository(doer, downloader, uploader, migrateOpts, nil); err != nil { if err1 := uploader.Rollback(); err1 != nil { log.Error("rollback failed: %v", err1) } diff --git a/services/migrations/gitbucket.go b/services/migrations/gitbucket.go index 92b6cac73..21d8c672d 100644 --- a/services/migrations/gitbucket.go +++ b/services/migrations/gitbucket.go @@ -6,9 +6,11 @@ package migrations import ( "context" + "fmt" "net/url" "strings" + "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/structs" ) @@ -37,6 +39,7 @@ func (f *GitBucketDownloaderFactory) New(ctx context.Context, opts base.MigrateO oldOwner := fields[1] oldName := strings.TrimSuffix(fields[2], ".git") + log.Trace("Create GitBucket downloader. BaseURL: %s RepoOwner: %s RepoName: %s", baseURL, oldOwner, oldName) return NewGitBucketDownloader(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil } @@ -51,6 +54,20 @@ type GitBucketDownloader struct { *GithubDownloaderV3 } +// String implements Stringer +func (g *GitBucketDownloader) String() string { + return fmt.Sprintf("migration from gitbucket server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + +// ColorFormat provides a basic color format for a GitBucketDownloader +func (g *GitBucketDownloader) ColorFormat(s fmt.State) { + if g == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from gitbucket server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + // NewGitBucketDownloader creates a GitBucket downloader func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GitBucketDownloader { githubDownloader := NewGithubDownloaderV3(ctx, baseURL, userName, password, token, repoOwner, repoName) diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index 4ad55894e..c52f30269 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -14,7 +14,6 @@ import ( "strings" "time" - admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/structs" @@ -71,6 +70,7 @@ type GiteaDownloader struct { base.NullDownloader ctx context.Context client *gitea_sdk.Client + baseURL string repoOwner string repoName string pagination bool @@ -78,8 +78,9 @@ type GiteaDownloader struct { } // NewGiteaDownloader creates a gitea Downloader via gitea API -// Use either a username/password or personal token. token is preferred -// Note: Public access only allows very basic access +// +// Use either a username/password or personal token. token is preferred +// Note: Public access only allows very basic access func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) (*GiteaDownloader, error) { giteaClient, err := gitea_sdk.NewClient( baseURL, @@ -116,6 +117,7 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo return &GiteaDownloader{ ctx: ctx, client: giteaClient, + baseURL: baseURL, repoOwner: path[0], repoName: path[1], pagination: paginationSupport, @@ -128,6 +130,20 @@ func (g *GiteaDownloader) SetContext(ctx context.Context) { g.ctx = ctx } +// String implements Stringer +func (g *GiteaDownloader) String() string { + return fmt.Sprintf("migration from gitea server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + +// ColorFormat provides a basic color format for a GiteaDownloader +func (g *GiteaDownloader) ColorFormat(s fmt.State) { + if g == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from gitea server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + // GetRepoInfo returns a repository information func (g *GiteaDownloader) GetRepoInfo() (*base.Repository, error) { if g == nil { @@ -283,6 +299,12 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele if err != nil { return nil, err } + + if !hasBaseURL(asset.DownloadURL, g.baseURL) { + WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.ID, g, asset.DownloadURL) + return io.NopCloser(strings.NewReader(asset.DownloadURL)), nil + } + // FIXME: for a private download? req, err := http.NewRequest("GET", asset.DownloadURL, nil) if err != nil { @@ -402,11 +424,7 @@ func (g *GiteaDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, err reactions, err := g.getIssueReactions(issue.Index) if err != nil { - log.Warn("Unable to load reactions during migrating issue #%d to %s/%s. Error: %v", issue.Index, g.repoOwner, g.repoName, err) - if err2 := admin_model.CreateRepositoryNotice( - fmt.Sprintf("Unable to load reactions during migrating issue #%d to %s/%s. Error: %v", issue.Index, g.repoOwner, g.repoName, err)); err2 != nil { - log.Error("create repository notice failed: ", err2) - } + WarnAndNotice("Unable to load reactions during migrating issue #%d in %s. Error: %v", issue.Index, g, err) } var assignees []string @@ -464,11 +482,7 @@ func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Com for _, comment := range comments { reactions, err := g.getCommentReactions(comment.ID) if err != nil { - log.Warn("Unable to load comment reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", commentable.GetForeignIndex(), comment.ID, g.repoOwner, g.repoName, err) - if err2 := admin_model.CreateRepositoryNotice( - fmt.Sprintf("Unable to load reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", commentable.GetForeignIndex(), comment.ID, g.repoOwner, g.repoName, err)); err2 != nil { - log.Error("create repository notice failed: ", err2) - } + WarnAndNotice("Unable to load comment reactions during migrating issue #%d for comment %d in %s. Error: %v", commentable.GetForeignIndex(), comment.ID, g, err) } allComments = append(allComments, &base.Comment{ @@ -543,11 +557,7 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques reactions, err := g.getIssueReactions(pr.Index) if err != nil { - log.Warn("Unable to load reactions during migrating pull #%d to %s/%s. Error: %v", pr.Index, g.repoOwner, g.repoName, err) - if err2 := admin_model.CreateRepositoryNotice( - fmt.Sprintf("Unable to load reactions during migrating pull #%d to %s/%s. Error: %v", pr.Index, g.repoOwner, g.repoName, err)); err2 != nil { - log.Error("create repository notice failed: ", err2) - } + WarnAndNotice("Unable to load reactions during migrating pull #%d in %s. Error: %v", pr.Index, g, err) } var assignees []string @@ -604,6 +614,8 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques }, ForeignIndex: pr.Index, }) + // SECURITY: Ensure that the PR is safe + _ = CheckAndEnsureSafePR(allPRs[len(allPRs)-1], g.baseURL, g) } isEnd := len(prs) < perPage diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index c7a6f9b02..5bf77e633 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "os" + "path" "path/filepath" "strconv" "strings" @@ -32,7 +33,7 @@ import ( "code.gitea.io/gitea/modules/uri" "code.gitea.io/gitea/services/pull" - gouuid "github.com/google/uuid" + "github.com/google/uuid" ) var _ base.Uploader = &GiteaLocalUploader{} @@ -48,7 +49,7 @@ type GiteaLocalUploader struct { milestones map[string]int64 issues map[int64]*issues_model.Issue gitRepo *git.Repository - prHeadCache map[string]struct{} + prHeadCache map[string]string sameApp bool userMap map[int64]int64 // external user id mapping to user id prCache map[int64]*issues_model.PullRequest @@ -65,7 +66,7 @@ func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner labels: make(map[string]*issues_model.Label), milestones: make(map[string]int64), issues: make(map[int64]*issues_model.Issue), - prHeadCache: make(map[string]struct{}), + prHeadCache: make(map[string]string), userMap: make(map[int64]int64), prCache: make(map[int64]*issues_model.PullRequest), } @@ -83,7 +84,7 @@ func (g *GiteaLocalUploader) MaxBatchInsertSize(tp string) int { case "label": return db.MaxBatchInsertSize(new(issues_model.Label)) case "release": - return db.MaxBatchInsertSize(new(models.Release)) + return db.MaxBatchInsertSize(new(repo_model.Release)) case "pullrequest": return db.MaxBatchInsertSize(new(issues_model.PullRequest)) } @@ -99,7 +100,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate var r *repo_model.Repository if opts.MigrateToRepoID <= 0 { - r, err = repo_module.CreateRepository(g.doer, owner, models.CreateRepoOptions{ + r, err = repo_module.CreateRepository(g.doer, owner, repo_module.CreateRepoOptions{ Name: g.repoName, Description: repo.Description, OriginalURL: repo.OriginalURL, @@ -125,7 +126,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate Mirror: repo.IsMirror, LFS: opts.LFS, LFSEndpoint: opts.LFSEndpoint, - CloneAddr: repo.CloneURL, + CloneAddr: repo.CloneURL, // SECURITY: we will assume that this has already been checked Private: repo.IsPrivate, Wiki: opts.Wiki, Releases: opts.Releases, // if didn't get releases, then sync them from tags @@ -150,13 +151,15 @@ func (g *GiteaLocalUploader) Close() { // CreateTopics creates topics func (g *GiteaLocalUploader) CreateTopics(topics ...string) error { - // ignore topics to long for the db + // Ignore topics too long for the db c := 0 - for i := range topics { - if len(topics[i]) <= 50 { - topics[c] = topics[i] - c++ + for _, topic := range topics { + if len(topic) > 50 { + continue } + + topics[c] = topic + c++ } topics = topics[:c] return repo_model.SaveTopics(g.repo.ID, topics...) @@ -217,11 +220,17 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { lbs := make([]*issues_model.Label, 0, len(labels)) for _, label := range labels { + // We must validate color here: + if !issues_model.LabelColorPattern.MatchString("#" + label.Color) { + log.Warn("Invalid label color: #%s for label: %s in migration to %s/%s", label.Color, label.Name, g.repoOwner, g.repoName) + label.Color = "ffffff" + } + lbs = append(lbs, &issues_model.Label{ RepoID: g.repo.ID, Name: label.Name, Description: label.Description, - Color: fmt.Sprintf("#%s", label.Color), + Color: "#" + label.Color, }) } @@ -237,7 +246,7 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { // CreateReleases creates releases func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { - rels := make([]*models.Release, 0, len(releases)) + rels := make([]*repo_model.Release, 0, len(releases)) for _, release := range releases { if release.Created.IsZero() { if !release.Published.IsZero() { @@ -247,7 +256,17 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { } } - rel := models.Release{ + // SECURITY: The TagName must be a valid git ref + if release.TagName != "" && !git.IsValidRefPattern(release.TagName) { + release.TagName = "" + } + + // SECURITY: The TargetCommitish must be a valid git ref + if release.TargetCommitish != "" && !git.IsValidRefPattern(release.TargetCommitish) { + release.TargetCommitish = "" + } + + rel := repo_model.Release{ RepoID: g.repo.ID, TagName: release.TagName, LowerTagName: strings.ToLower(release.TagName), @@ -288,14 +307,15 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { } } attach := repo_model.Attachment{ - UUID: gouuid.New().String(), + UUID: uuid.New().String(), Name: asset.Name, DownloadCount: int64(*asset.DownloadCount), Size: int64(*asset.Size), CreatedUnix: timeutil.TimeStamp(asset.Created.Unix()), } - // download attachment + // SECURITY: We cannot check the DownloadURL and DownloadFunc are safe here + // ... we must assume that they are safe and simply download the attachment err := func() error { // asset.DownloadURL maybe a local file var rc io.ReadCloser @@ -365,6 +385,12 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { } } + // SECURITY: issue.Ref needs to be a valid reference + if !git.IsValidRefPattern(issue.Ref) { + log.Warn("Invalid issue.Ref[%s] in issue #%d in %s/%s", issue.Ref, issue.Number, g.repoOwner, g.repoName) + issue.Ref = "" + } + is := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, @@ -496,102 +522,151 @@ func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error } func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head string, err error) { - // download patch file + // SECURITY: this pr must have been must have been ensured safe + if !pr.EnsuredSafe { + log.Error("PR #%d in %s/%s has not been checked for safety.", pr.Number, g.repoOwner, g.repoName) + return "", fmt.Errorf("the PR[%d] was not checked for safety", pr.Number) + } + + // Anonymous function to download the patch file (allows us to use defer) err = func() error { + // if the patchURL is empty there is nothing to download if pr.PatchURL == "" { return nil } - // pr.PatchURL maybe a local file - ret, err := uri.Open(pr.PatchURL) + + // SECURITY: We will assume that the pr.PatchURL has been checked + // pr.PatchURL maybe a local file - but note EnsureSafe should be asserting that this safe + ret, err := uri.Open(pr.PatchURL) // TODO: This probably needs to use the downloader as there may be rate limiting issues here if err != nil { return err } defer ret.Close() + pullDir := filepath.Join(g.repo.RepoPath(), "pulls") if err = os.MkdirAll(pullDir, os.ModePerm); err != nil { return err } + f, err := os.Create(filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number))) if err != nil { return err } defer f.Close() + + // TODO: Should there be limits on the size of this file? _, err = io.Copy(f, ret) + return err }() if err != nil { return "", err } - // set head information - pullHead := filepath.Join(g.repo.RepoPath(), "refs", "pull", fmt.Sprintf("%d", pr.Number)) - if err := os.MkdirAll(pullHead, os.ModePerm); err != nil { - return "", err - } - p, err := os.Create(filepath.Join(pullHead, "head")) - if err != nil { - return "", err - } - _, err = p.WriteString(pr.Head.SHA) - p.Close() - if err != nil { - return "", err - } - head = "unknown repository" if pr.IsForkPullRequest() && pr.State != "closed" { - if pr.Head.OwnerName != "" { - remote := pr.Head.OwnerName - _, ok := g.prHeadCache[remote] - if !ok { - // git remote add - err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true) - if err != nil { - log.Error("AddRemote failed: %s", err) - } else { - g.prHeadCache[remote] = struct{}{} - ok = true + // OK we want to fetch the current head as a branch from its CloneURL + + // 1. Is there a head clone URL available? + // 2. Is there a head ref available? + if pr.Head.CloneURL == "" || pr.Head.Ref == "" { + return head, nil + } + + // 3. We need to create a remote for this clone url + // ... maybe we already have a name for this remote + remote, ok := g.prHeadCache[pr.Head.CloneURL+":"] + if !ok { + // ... let's try ownername as a reasonable name + remote = pr.Head.OwnerName + if !git.IsValidRefPattern(remote) { + // ... let's try something less nice + remote = "head-pr-" + strconv.FormatInt(pr.Number, 10) + } + // ... now add the remote + err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true) + if err != nil { + log.Error("PR #%d in %s/%s AddRemote[%s] failed: %v", pr.Number, g.repoOwner, g.repoName, remote, err) + } else { + g.prHeadCache[pr.Head.CloneURL+":"] = remote + ok = true + } + } + if !ok { + return head, nil + } + + // 4. Check if we already have this ref? + localRef, ok := g.prHeadCache[pr.Head.CloneURL+":"+pr.Head.Ref] + if !ok { + // ... We would normally name this migrated branch as / but we need to ensure that is safe + localRef = git.SanitizeRefPattern(pr.Head.OwnerName + "/" + pr.Head.Ref) + + // ... Now we must assert that this does not exist + if g.gitRepo.IsBranchExist(localRef) { + localRef = "head-pr-" + strconv.FormatInt(pr.Number, 10) + "/" + localRef + i := 0 + for g.gitRepo.IsBranchExist(localRef) { + if i > 5 { + // ... We tried, we really tried but this is just a seriously unfriendly repo + return head, nil + } + // OK just try some uuids! + localRef = git.SanitizeRefPattern("head-pr-" + strconv.FormatInt(pr.Number, 10) + uuid.New().String()) + i++ } } - if ok { - _, _, err = git.NewCommand(g.ctx, "fetch", "--no-tags", "--", remote, pr.Head.Ref).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) - if err != nil { - log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) - } else { - headBranch := filepath.Join(g.repo.RepoPath(), "refs", "heads", pr.Head.OwnerName, pr.Head.Ref) - if err := os.MkdirAll(filepath.Dir(headBranch), os.ModePerm); err != nil { - return "", err - } - b, err := os.Create(headBranch) - if err != nil { - return "", err - } - _, err = b.WriteString(pr.Head.SHA) - b.Close() - if err != nil { - return "", err - } - head = pr.Head.OwnerName + "/" + pr.Head.Ref - } + fetchArg := pr.Head.Ref + ":" + git.BranchPrefix + localRef + if strings.HasPrefix(fetchArg, "-") { + fetchArg = git.BranchPrefix + fetchArg } + + _, _, err = git.NewCommand(g.ctx, "fetch", "--no-tags", "--", remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + if err != nil { + log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) + return head, nil + } + g.prHeadCache[pr.Head.CloneURL+":"+pr.Head.Ref] = localRef + head = localRef } - } else { + + // 5. Now if pr.Head.SHA == "" we should recover this to the head of this branch + if pr.Head.SHA == "" { + headSha, err := g.gitRepo.GetBranchCommitID(localRef) + if err != nil { + log.Error("unable to get head SHA of local head for PR #%d from %s in %s/%s. Error: %v", pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) + return head, nil + } + pr.Head.SHA = headSha + } + + _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref", pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + if err != nil { + return "", err + } + + return head, nil + } + + if pr.Head.Ref != "" { head = pr.Head.Ref - // Ensure the closed PR SHA still points to an existing ref + } + + // Ensure the closed PR SHA still points to an existing ref + if pr.Head.SHA == "" { + // The SHA is empty + log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName) + } else { _, _, err = git.NewCommand(g.ctx, "rev-list", "--quiet", "-1", pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { - if pr.Head.SHA != "" { - // Git update-ref remove bad references with a relative path - log.Warn("Deprecated local head, removing : %v", pr.Head.SHA) - err = g.gitRepo.RemoveReference(pr.GetGitRefName()) - } else { - // The SHA is empty, remove the head file - log.Warn("Empty reference, removing : %v", pullHead) - err = os.Remove(filepath.Join(pullHead, "head")) - } + // Git update-ref remove bad references with a relative path + log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitRefName()) + } else { + // set head information + _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref", pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { - log.Error("Cannot remove local head ref, %v", err) + log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) } } } @@ -615,6 +690,20 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model return nil, fmt.Errorf("updateGitForPullRequest: %w", err) } + // Now we may need to fix the mergebase + if pr.Base.SHA == "" { + if pr.Base.Ref != "" && pr.Head.SHA != "" { + // A PR against a tag base does not make sense - therefore pr.Base.Ref must be a branch + // TODO: should we be checking for the refs/heads/ prefix on the pr.Base.Ref? (i.e. are these actually branches or refs) + pr.Base.SHA, _, err = g.gitRepo.GetMergeBase("", git.BranchPrefix+pr.Base.Ref, pr.Head.SHA) + if err != nil { + log.Error("Cannot determine the merge base for PR #%d in %s/%s. Error: %v", pr.Number, g.repoOwner, g.repoName, err) + } + } else { + log.Error("Cannot determine the merge base for PR #%d in %s/%s. Not enough information", pr.Number, g.repoOwner, g.repoName) + } + } + if pr.Created.IsZero() { if pr.Closed != nil { pr.Created = *pr.Closed @@ -728,6 +817,8 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { return err } + cms = append(cms, &cm) + // get pr pr, ok := g.prCache[issue.ID] if !ok { @@ -738,6 +829,17 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { } g.prCache[issue.ID] = pr } + if pr.MergeBase == "" { + // No mergebase -> no basis for any patches + log.Warn("PR #%d in %s/%s: does not have a merge base, all review comments will be ignored", pr.Index, g.repoOwner, g.repoName) + continue + } + + headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitRefName()) + if err != nil { + log.Warn("PR #%d GetRefCommitID[%s] in %s/%s: %v, all review comments will be ignored", pr.Index, pr.GetGitRefName(), g.repoOwner, g.repoName, err) + continue + } for _, comment := range review.Comments { line := comment.Line @@ -746,11 +848,9 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { } else { _, _, line, _ = git.ParseDiffHunkString(comment.DiffHunk) } - headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitRefName()) - if err != nil { - log.Warn("GetRefCommitID[%s]: %v, the review comment will be ignored", pr.GetGitRefName(), err) - continue - } + + // SECURITY: The TreePath must be cleaned! + comment.TreePath = path.Clean("/" + comment.TreePath)[1:] var patch string reader, writer := io.Pipe() @@ -775,6 +875,11 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { comment.UpdatedAt = comment.CreatedAt } + if !git.IsValidSHAPattern(comment.CommitID) { + log.Warn("Invalid comment CommitID[%s] on comment[%d] in PR #%d of %s/%s replaced with %s", comment.CommitID, pr.Index, g.repoOwner, g.repoName, headCommitID) + comment.CommitID = headCommitID + } + c := issues_model.Comment{ Type: issues_model.CommentTypeCode, IssueID: issue.ID, @@ -793,8 +898,6 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { cm.Comments = append(cm.Comments, &c) } - - cms = append(cms, &cm) } return issues_model.InsertReviews(cms) diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 9fb3d6ffd..af6230dec 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -15,7 +15,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -46,7 +45,7 @@ func TestGiteaUploadRepo(t *testing.T) { uploader = NewGiteaLocalUploader(graceful.GetManager().HammerContext(), user, user.Name, repoName) ) - err := migrateRepository(downloader, uploader, base.MigrateOptions{ + err := migrateRepository(user, downloader, uploader, base.MigrateOptions{ CloneAddr: "https://github.com/go-xorm/builder", RepoName: repoName, AuthUsername: "", @@ -85,7 +84,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, labels, 12) - releases, err := models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{ + releases, err := repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, @@ -95,7 +94,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, releases, 8) - releases, err = models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{ + releases, err = repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, @@ -146,7 +145,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { // The externalID does not match any existing user, everything // belongs to the doer // - target := models.Release{} + target := repo_model.Release{} uploader.userMap = make(map[int64]int64) err := uploader.remapUser(&source, &target) assert.NoError(t, err) @@ -157,7 +156,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { // everything belongs to the doer // source.PublisherID = user.ID - target = models.Release{} + target = repo_model.Release{} uploader.userMap = make(map[int64]int64) err = uploader.remapUser(&source, &target) assert.NoError(t, err) @@ -168,7 +167,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { // belongs to the existing user // source.PublisherName = user.Name - target = models.Release{} + target = repo_model.Release{} uploader.userMap = make(map[int64]int64) err = uploader.remapUser(&source, &target) assert.NoError(t, err) @@ -197,7 +196,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { // by the doer // uploader.userMap = make(map[int64]int64) - target := models.Release{} + target := repo_model.Release{} err := uploader.remapUser(&source, &target) assert.NoError(t, err) assert.EqualValues(t, doer.ID, target.GetUserID()) @@ -220,7 +219,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { // the migrated data // uploader.userMap = make(map[int64]int64) - target = models.Release{} + target = repo_model.Release{} err = uploader.remapUser(&source, &target) assert.NoError(t, err) assert.EqualValues(t, linkedUser.ID, target.GetUserID()) @@ -391,7 +390,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { }, }, assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "AddRemote failed") + assert.Contains(t, content, "AddRemote") }, }, { @@ -440,7 +439,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { }, }, assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "Empty reference, removing") + assert.Contains(t, content, "Empty reference") assert.NotContains(t, content, "Cannot remove local head") }, }, @@ -468,7 +467,6 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { }, assertContent: func(t *testing.T, content string) { assert.Contains(t, content, "Deprecated local head") - assert.Contains(t, content, "Cannot remove local head") }, }, { @@ -505,6 +503,8 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { logger.SetLogger("buffer", "buffer", "{}") defer logger.DelLogger("buffer") + testCase.pr.EnsuredSafe = true + head, err := uploader.updateGitForPullRequest(&testCase.pr) assert.NoError(t, err) assert.EqualValues(t, testCase.head, head) diff --git a/services/migrations/github.go b/services/migrations/github.go index 5f5b430fa..0ffdbb042 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -51,7 +51,7 @@ func (f *GithubDownloaderV3Factory) New(ctx context.Context, opts base.MigrateOp oldOwner := fields[1] oldName := strings.TrimSuffix(fields[2], ".git") - log.Trace("Create github downloader: %s/%s", oldOwner, oldName) + log.Trace("Create github downloader BaseURL: %s %s/%s", baseURL, oldOwner, oldName) return NewGithubDownloaderV3(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil } @@ -67,6 +67,7 @@ type GithubDownloaderV3 struct { base.NullDownloader ctx context.Context clients []*github.Client + baseURL string repoOwner string repoName string userName string @@ -81,6 +82,7 @@ type GithubDownloaderV3 struct { func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 { downloader := GithubDownloaderV3{ userName: userName, + baseURL: baseURL, password: password, ctx: ctx, repoOwner: repoOwner, @@ -118,6 +120,20 @@ func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, tok return &downloader } +// String implements Stringer +func (g *GithubDownloaderV3) String() string { + return fmt.Sprintf("migration from github server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + +// ColorFormat provides a basic color format for a GithubDownloader +func (g *GithubDownloaderV3) ColorFormat(s fmt.State) { + if g == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from github server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + func (g *GithubDownloaderV3) addClient(client *http.Client, baseURL string) { githubClient := github.NewClient(client) if baseURL != "https://github.com" { @@ -322,33 +338,44 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) Updated: asset.UpdatedAt.Time, DownloadFunc: func() (io.ReadCloser, error) { g.waitAndPickClient() - asset, redirectURL, err := g.getClient().Repositories.DownloadReleaseAsset(g.ctx, g.repoOwner, g.repoName, assetID, nil) + readCloser, redirectURL, err := g.getClient().Repositories.DownloadReleaseAsset(g.ctx, g.repoOwner, g.repoName, assetID, nil) if err != nil { return nil, err } if err := g.RefreshRate(); err != nil { log.Error("g.getClient().RateLimits: %s", err) } - if asset == nil { - if redirectURL != "" { - g.waitAndPickClient() - req, err := http.NewRequestWithContext(g.ctx, "GET", redirectURL, nil) - if err != nil { - return nil, err - } - resp, err := httpClient.Do(req) - err1 := g.RefreshRate() - if err1 != nil { - log.Error("g.getClient().RateLimits: %s", err1) - } - if err != nil { - return nil, err - } - return resp.Body, nil - } - return nil, fmt.Errorf("No release asset found for %d", assetID) + + if readCloser != nil { + return readCloser, nil } - return asset, nil + + if redirectURL == "" { + return nil, fmt.Errorf("no release asset found for %d", assetID) + } + + // Prevent open redirect + if !hasBaseURL(redirectURL, g.baseURL) && + !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") { + WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.GetID(), g, redirectURL) + + return io.NopCloser(strings.NewReader(redirectURL)), nil + } + + g.waitAndPickClient() + req, err := http.NewRequestWithContext(g.ctx, "GET", redirectURL, nil) + if err != nil { + return nil, err + } + resp, err := httpClient.Do(req) + err1 := g.RefreshRate() + if err1 != nil { + log.Error("g.RefreshRate(): %s", err1) + } + if err != nil { + return nil, err + } + return resp.Body, nil }, }) } @@ -697,7 +724,7 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq SHA: pr.GetHead().GetSHA(), OwnerName: pr.GetHead().GetUser().GetLogin(), RepoName: pr.GetHead().GetRepo().GetName(), - CloneURL: pr.GetHead().GetRepo().GetCloneURL(), + CloneURL: pr.GetHead().GetRepo().GetCloneURL(), // see below for SECURITY related issues here }, Base: base.PullRequestBranch{ Ref: pr.GetBase().GetRef(), @@ -705,10 +732,13 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq RepoName: pr.GetBase().GetRepo().GetName(), OwnerName: pr.GetBase().GetUser().GetLogin(), }, - PatchURL: pr.GetPatchURL(), + PatchURL: pr.GetPatchURL(), // see below for SECURITY related issues here Reactions: reactions, ForeignIndex: int64(*pr.Number), }) + + // SECURITY: Ensure that the PR is safe + _ = CheckAndEnsureSafePR(allPRs[len(allPRs)-1], g.baseURL, g) } return allPRs, len(prs) < perPage, nil diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 549e3cb65..95bec59e8 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -63,6 +63,7 @@ type GitlabDownloader struct { base.NullDownloader ctx context.Context client *gitlab.Client + baseURL string repoID int repoName string issueCount int64 @@ -70,8 +71,9 @@ type GitlabDownloader struct { } // NewGitlabDownloader creates a gitlab Downloader via gitlab API -// Use either a username/password, personal token entered into the username field, or anonymous/public access -// Note: Public access only allows very basic access +// +// Use either a username/password, personal token entered into the username field, or anonymous/public access +// Note: Public access only allows very basic access func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) (*GitlabDownloader, error) { gitlabClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL), gitlab.WithHTTPClient(NewMigrationHTTPClient())) // Only use basic auth if token is blank and password is NOT @@ -124,12 +126,27 @@ func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, passw return &GitlabDownloader{ ctx: ctx, client: gitlabClient, + baseURL: baseURL, repoID: gr.ID, repoName: gr.Name, maxPerPage: 100, }, nil } +// String implements Stringer +func (g *GitlabDownloader) String() string { + return fmt.Sprintf("migration from gitlab server %s [%d]/%s", g.baseURL, g.repoID, g.repoName) +} + +// ColorFormat provides a basic color format for a GitlabDownloader +func (g *GitlabDownloader) ColorFormat(s fmt.State) { + if g == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from gitlab server %s [%d]/%s", g.baseURL, g.repoID, g.repoName) +} + // SetContext set context func (g *GitlabDownloader) SetContext(ctx context.Context) { g.ctx = ctx @@ -307,6 +324,11 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea return nil, err } + if !hasBaseURL(link.URL, g.baseURL) { + WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.ID, g, link.URL) + return io.NopCloser(strings.NewReader(link.URL)), nil + } + req, err := http.NewRequest("GET", link.URL, nil) if err != nil { return nil, err @@ -353,7 +375,8 @@ type gitlabIssueContext struct { } // GetIssues returns issues according start and limit -// Note: issue label description and colors are not supported by the go-gitlab library at this time +// +// Note: issue label description and colors are not supported by the go-gitlab library at this time func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { state := "all" sort := "asc" @@ -610,6 +633,9 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque ForeignIndex: int64(pr.IID), Context: gitlabIssueContext{IsMergeRequest: true}, }) + + // SECURITY: Ensure that the PR is safe + _ = CheckAndEnsureSafePR(allPRs[len(allPRs)-1], g.baseURL, g) } return allPRs, len(prs) < perPage, nil diff --git a/services/migrations/gogs.go b/services/migrations/gogs.go index a28033218..46cc3ca41 100644 --- a/services/migrations/gogs.go +++ b/services/migrations/gogs.go @@ -73,6 +73,20 @@ type GogsDownloader struct { transport http.RoundTripper } +// String implements Stringer +func (g *GogsDownloader) String() string { + return fmt.Sprintf("migration from gogs server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + +// ColorFormat provides a basic color format for a GogsDownloader +func (g *GogsDownloader) ColorFormat(s fmt.State) { + if g == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from gogs server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) +} + // SetContext set context func (g *GogsDownloader) SetContext(ctx context.Context) { g.ctx = ctx diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 9460c66db..040f0aebb 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -128,7 +128,7 @@ func MigrateRepository(ctx context.Context, doer *user_model.User, ownerName str uploader := NewGiteaLocalUploader(ctx, doer, ownerName, opts.RepoName) uploader.gitServiceType = opts.GitServiceType - if err := migrateRepository(downloader, uploader, opts, messenger); err != nil { + if err := migrateRepository(doer, downloader, uploader, opts, messenger); err != nil { if err1 := uploader.Rollback(); err1 != nil { log.Error("rollback failed: %v", err1) } @@ -177,7 +177,7 @@ func newDownloader(ctx context.Context, ownerName string, opts base.MigrateOptio // migrateRepository will download information and then upload it to Uploader, this is a simple // process for small repository. For a big repository, save all the data to disk // before upload is better -func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error { +func migrateRepository(doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error { if messenger == nil { messenger = base.NilMessenger } @@ -198,6 +198,27 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts return err } + // SECURITY: If the downloader is not a RepositoryRestorer then we need to recheck the CloneURL + if _, ok := downloader.(*RepositoryRestorer); !ok { + // Now the clone URL can be rewritten by the downloader so we must recheck + if err := IsMigrateURLAllowed(repo.CloneURL, doer); err != nil { + return err + } + + // SECURITY: Ensure that we haven't been redirected from an external to a local filesystem + // Now we know all of these must parse + cloneAddrURL, _ := url.Parse(opts.CloneAddr) + cloneURL, _ := url.Parse(repo.CloneURL) + + if cloneURL.Scheme == "file" || cloneURL.Scheme == "" { + if cloneAddrURL.Scheme != "file" && cloneAddrURL.Scheme != "" { + return fmt.Errorf("repo info has changed from external to local filesystem") + } + } + + // We don't actually need to check the OriginalURL as it isn't used anywhere + } + log.Trace("migrating git data from %s", repo.CloneURL) messenger("repo.migrate.migrating_git") if err = uploader.CreateRepo(repo, opts); err != nil { diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index a46ba35f7..8cc826c3b 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -110,6 +110,20 @@ func NewOneDevDownloader(ctx context.Context, baseURL *url.URL, username, passwo return downloader } +// String implements Stringer +func (d *OneDevDownloader) String() string { + return fmt.Sprintf("migration from oneDev server %s [%d]/%s", d.baseURL, d.repoID, d.repoName) +} + +// ColorFormat provides a basic color format for a OneDevDownloader +func (d *OneDevDownloader) ColorFormat(s fmt.State) { + if d == nil { + log.ColorFprintf(s, "") + return + } + log.ColorFprintf(s, "migration from oneDev server %s [%d]/%s", d.baseURL, d.repoID, d.repoName) +} + func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, result interface{}) error { u, err := d.baseURL.Parse(endpoint) if err != nil { @@ -542,6 +556,9 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque ForeignIndex: pr.ID, Context: onedevIssueContext{IsPullRequest: true}, }) + + // SECURITY: Ensure that the PR is safe + _ = CheckAndEnsureSafePR(pullRequests[len(pullRequests)-1], d.baseURL.String(), d) } return pullRequests, len(pullRequests) == 0, nil diff --git a/services/migrations/restore.go b/services/migrations/restore.go index 8c9654a7e..c3fbcbb25 100644 --- a/services/migrations/restore.go +++ b/services/migrations/restore.go @@ -243,6 +243,7 @@ func (r *RepositoryRestorer) GetPullRequests(page, perPage int) ([]*base.PullReq } for _, pr := range pulls { pr.PatchURL = "file://" + filepath.Join(r.baseDir, pr.PatchURL) + CheckAndEnsureSafePR(pr, "", r) } return pulls, true, nil } diff --git a/services/org/repo.go b/services/org/repo.go new file mode 100644 index 000000000..769419d45 --- /dev/null +++ b/services/org/repo.go @@ -0,0 +1,28 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package org + +import ( + "context" + "errors" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" +) + +// TeamAddRepository adds new repository to team of organization. +func TeamAddRepository(t *organization.Team, repo *repo_model.Repository) (err error) { + if repo.OwnerID != t.OrgID { + return errors.New("repository does not belong to organization") + } else if models.HasRepository(t, repo.ID) { + return nil + } + + return db.WithTx(func(ctx context.Context) error { + return models.AddRepository(ctx, t, repo) + }) +} diff --git a/services/org/repo_test.go b/services/org/repo_test.go new file mode 100644 index 000000000..21158bfa2 --- /dev/null +++ b/services/org/repo_test.go @@ -0,0 +1,34 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package org + +import ( + "testing" + + "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" +) + +func TestTeam_AddRepository(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + testSuccess := func(teamID, repoID int64) { + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) + assert.NoError(t, TeamAddRepository(team, repo)) + unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) + unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) + } + testSuccess(2, 3) + testSuccess(2, 5) + + team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + assert.Error(t, TeamAddRepository(team, repo)) + unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1}) +} diff --git a/services/packages/packages.go b/services/packages/packages.go index 4bc31a34e..96132eac0 100644 --- a/services/packages/packages.go +++ b/services/packages/packages.go @@ -402,7 +402,7 @@ func Cleanup(unused context.Context, olderThan time.Duration) error { } // GetFileStreamByPackageNameAndVersion returns the content of the specific package file -func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadCloser, *packages_model.PackageFile, error) { +func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) { log.Trace("Getting package file stream: %v, %v, %s, %s, %s, %s", pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version, pfi.Filename, pfi.CompositeKey) pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version) @@ -418,7 +418,7 @@ func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, } // GetFileStreamByPackageVersionAndFileID returns the content of the specific package file -func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_model.User, versionID, fileID int64) (io.ReadCloser, *packages_model.PackageFile, error) { +func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_model.User, versionID, fileID int64) (io.ReadSeekCloser, *packages_model.PackageFile, error) { log.Trace("Getting package file stream: %v, %v, %v", owner.ID, versionID, fileID) pv, err := packages_model.GetVersionByID(ctx, versionID) @@ -449,7 +449,7 @@ func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_mod } // GetFileStreamByPackageVersion returns the content of the specific package file -func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadCloser, *packages_model.PackageFile, error) { +func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) { pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, pfi.Filename, pfi.CompositeKey) if err != nil { return nil, nil, err @@ -459,7 +459,7 @@ func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.Packa } // GetPackageFileStream returns the content of the specific package file -func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadCloser, *packages_model.PackageFile, error) { +func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadSeekCloser, *packages_model.PackageFile, error) { pb, err := packages_model.GetBlobByID(ctx, pf.BlobID) if err != nil { return nil, nil, err diff --git a/services/release/release.go b/services/release/release.go index 6fa966de1..ae610b0e3 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -23,7 +23,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" ) -func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool, error) { +func createTag(gitRepo *git.Repository, rel *repo_model.Release, msg string) (bool, error) { var created bool // Only actual create when publish. if !rel.IsDraft { @@ -37,6 +37,9 @@ func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool, if err != nil { return false, fmt.Errorf("GetProtectedTags: %v", err) } + + // Trim '--' prefix to prevent command line argument vulnerability. + rel.TagName = strings.TrimPrefix(rel.TagName, "--") isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, rel.TagName, rel.PublisherID) if err != nil { return false, err @@ -52,8 +55,6 @@ func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool, return false, fmt.Errorf("createTag::GetCommit[%v]: %v", rel.Target, err) } - // Trim '--' prefix to prevent command line argument vulnerability. - rel.TagName = strings.TrimPrefix(rel.TagName, "--") if len(msg) > 0 { if err = gitRepo.CreateAnnotatedTag(rel.TagName, msg, commit.ID.String()); err != nil { if strings.Contains(err.Error(), "is not a valid tag name") { @@ -112,12 +113,12 @@ func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool, } // CreateRelease creates a new release of repository. -func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string, msg string) error { - has, err := models.IsReleaseExist(gitRepo.Ctx, rel.RepoID, rel.TagName) +func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, attachmentUUIDs []string, msg string) error { + has, err := repo_model.IsReleaseExist(gitRepo.Ctx, rel.RepoID, rel.TagName) if err != nil { return err } else if has { - return models.ErrReleaseAlreadyExist{ + return repo_model.ErrReleaseAlreadyExist{ TagName: rel.TagName, } } @@ -131,7 +132,7 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs return err } - if err = models.AddReleaseAttachments(gitRepo.Ctx, rel.ID, attachmentUUIDs); err != nil { + if err = repo_model.AddReleaseAttachments(gitRepo.Ctx, rel.ID, attachmentUUIDs); err != nil { return err } @@ -144,7 +145,7 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs // CreateNewTag creates a new repository tag func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commit, tagName, msg string) error { - has, err := models.IsReleaseExist(ctx, repo.ID, tagName) + has, err := repo_model.IsReleaseExist(ctx, repo.ID, tagName) if err != nil { return err } else if has { @@ -159,7 +160,7 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R } defer closer.Close() - rel := &models.Release{ + rel := &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: doer.ID, @@ -182,7 +183,7 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R // addAttachmentUUIDs accept a slice of new created attachments' uuids which will be reassigned release_id as the created release // delAttachmentUUIDs accept a slice of attachments' uuids which will be deleted from the release // editAttachments accept a map of attachment uuid to new attachment name which will be updated with attachments. -func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *models.Release, +func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_model.Release, addAttachmentUUIDs, delAttachmentUUIDs []string, editAttachments map[string]string, ) (err error) { if rel.ID == 0 { @@ -200,11 +201,11 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *models.R } defer committer.Close() - if err = models.UpdateRelease(ctx, rel); err != nil { + if err = repo_model.UpdateRelease(ctx, rel); err != nil { return err } - if err = models.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil { + if err = repo_model.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil { return fmt.Errorf("AddReleaseAttachments: %v", err) } @@ -283,7 +284,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *models.R // DeleteReleaseByID deletes a release and corresponding Git tag by given ID. func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, delTag bool) error { - rel, err := models.GetReleaseByID(ctx, id) + rel, err := repo_model.GetReleaseByID(ctx, id) if err != nil { return fmt.Errorf("GetReleaseByID: %v", err) } @@ -308,7 +309,7 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del } } - if stdout, _, err := git.NewCommand(ctx, "tag", "-d", rel.TagName). + if stdout, _, err := git.NewCommand(ctx, "tag", "-d", "--", rel.TagName). SetDescription(fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID)). RunStdString(&git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") { log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err) @@ -324,13 +325,13 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del }, repository.NewPushCommits()) notification.NotifyDeleteRef(doer, repo, "tag", git.TagPrefix+rel.TagName) - if err := models.DeleteReleaseByID(id); err != nil { + if err := repo_model.DeleteReleaseByID(id); err != nil { return fmt.Errorf("DeleteReleaseByID: %v", err) } } else { rel.IsTag = true - if err = models.UpdateRelease(ctx, rel); err != nil { + if err = repo_model.UpdateRelease(ctx, rel); err != nil { return fmt.Errorf("Update: %v", err) } } diff --git a/services/release/release_test.go b/services/release/release_test.go index d1a9298b6..c0cafb5fc 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -10,7 +10,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -38,7 +37,7 @@ func TestRelease_Create(t *testing.T) { assert.NoError(t, err) defer gitRepo.Close() - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -52,7 +51,7 @@ func TestRelease_Create(t *testing.T) { IsTag: false, }, nil, "")) - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -66,7 +65,7 @@ func TestRelease_Create(t *testing.T) { IsTag: false, }, nil, "")) - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -80,7 +79,7 @@ func TestRelease_Create(t *testing.T) { IsTag: false, }, nil, "")) - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -94,7 +93,7 @@ func TestRelease_Create(t *testing.T) { IsTag: false, }, nil, "")) - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -115,7 +114,7 @@ func TestRelease_Create(t *testing.T) { }, strings.NewReader("testtest")) assert.NoError(t, err) - release := models.Release{ + release := repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -143,7 +142,7 @@ func TestRelease_Update(t *testing.T) { defer gitRepo.Close() // Test a changed release - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -156,18 +155,18 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: false, IsTag: false, }, nil, "")) - release, err := models.GetRelease(repo.ID, "v1.1.1") + release, err := repo_model.GetRelease(repo.ID, "v1.1.1") assert.NoError(t, err) releaseCreatedUnix := release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp release.Note = "Changed note" assert.NoError(t, UpdateRelease(user, gitRepo, release, nil, nil, nil)) - release, err = models.GetReleaseByID(db.DefaultContext, release.ID) + release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) // Test a changed draft - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -180,18 +179,18 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: false, IsTag: false, }, nil, "")) - release, err = models.GetRelease(repo.ID, "v1.2.1") + release, err = repo_model.GetRelease(repo.ID, "v1.2.1") assert.NoError(t, err) releaseCreatedUnix = release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp release.Title = "Changed title" assert.NoError(t, UpdateRelease(user, gitRepo, release, nil, nil, nil)) - release, err = models.GetReleaseByID(db.DefaultContext, release.ID) + release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) assert.NoError(t, err) assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) // Test a changed pre-release - assert.NoError(t, CreateRelease(gitRepo, &models.Release{ + assert.NoError(t, CreateRelease(gitRepo, &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -204,19 +203,19 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: true, IsTag: false, }, nil, "")) - release, err = models.GetRelease(repo.ID, "v1.3.1") + release, err = repo_model.GetRelease(repo.ID, "v1.3.1") assert.NoError(t, err) releaseCreatedUnix = release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp release.Title = "Changed title" release.Note = "Changed note" assert.NoError(t, UpdateRelease(user, gitRepo, release, nil, nil, nil)) - release, err = models.GetReleaseByID(db.DefaultContext, release.ID) + release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) // Test create release - release = &models.Release{ + release = &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -236,7 +235,7 @@ func TestRelease_Update(t *testing.T) { tagName := release.TagName assert.NoError(t, UpdateRelease(user, gitRepo, release, nil, nil, nil)) - release, err = models.GetReleaseByID(db.DefaultContext, release.ID) + release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) assert.NoError(t, err) assert.Equal(t, tagName, release.TagName) @@ -249,7 +248,7 @@ func TestRelease_Update(t *testing.T) { assert.NoError(t, err) assert.NoError(t, UpdateRelease(user, gitRepo, release, []string{attach.UUID}, nil, nil)) - assert.NoError(t, models.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) assert.Len(t, release.Attachments, 1) assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID) assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID) @@ -260,7 +259,7 @@ func TestRelease_Update(t *testing.T) { attach.UUID: "test2.txt", })) release.Attachments = nil - assert.NoError(t, models.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) assert.Len(t, release.Attachments, 1) assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID) assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID) @@ -269,7 +268,7 @@ func TestRelease_Update(t *testing.T) { // delete the attachment assert.NoError(t, UpdateRelease(user, gitRepo, release, nil, []string{attach.UUID}, nil)) release.Attachments = nil - assert.NoError(t, models.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) assert.Empty(t, release.Attachments) } @@ -285,7 +284,7 @@ func TestRelease_createTag(t *testing.T) { defer gitRepo.Close() // Test a changed release - release := &models.Release{ + release := &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -309,7 +308,7 @@ func TestRelease_createTag(t *testing.T) { assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) // Test a changed draft - release = &models.Release{ + release = &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, @@ -332,7 +331,7 @@ func TestRelease_createTag(t *testing.T) { assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) // Test a changed pre-release - release = &models.Release{ + release = &repo_model.Release{ RepoID: repo.ID, Repo: repo, PublisherID: user.ID, diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 6d6611c70..74876d8e7 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -11,7 +11,6 @@ import ( "path/filepath" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -26,7 +25,7 @@ import ( ) // AdoptRepository adopts pre-existing repository files for the user/organization. -func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { +func AdoptRepository(doer, u *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) { if !doer.IsAdmin && !u.CanCreateRepo() { return nil, repo_model.ErrReachLimitOfRepo{ Limit: u.MaxRepoCreation, @@ -67,7 +66,7 @@ func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (* } } - if err := models.CreateRepository(ctx, doer, u, repo, true); err != nil { + if err := repo_module.CreateRepositoryByExample(ctx, doer, u, repo, true); err != nil { return err } if err := adoptRepository(ctx, repoPath, doer, repo, opts); err != nil { @@ -100,7 +99,7 @@ func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (* return repo, nil } -func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts models.CreateRepoOptions) (err error) { +func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts repo_module.CreateRepoOptions) (err error) { isExist, err := util.IsExist(repoPath) if err != nil { log.Error("Unable to check if %s exists. Error: %v", repoPath, err) diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index ebd3eaf23..ae43503ba 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -57,6 +57,21 @@ func (ErrUnknownArchiveFormat) Is(err error) bool { return ok } +// RepoRefNotFoundError is returned when a requested reference (commit, tag) was not found. +type RepoRefNotFoundError struct { + RefName string +} + +// Error implements error. +func (e RepoRefNotFoundError) Error() string { + return fmt.Sprintf("unrecognized repository reference: %s", e.RefName) +} + +func (e RepoRefNotFoundError) Is(err error) bool { + _, ok := err.(RepoRefNotFoundError) + return ok +} + // NewRequest creates an archival request, based on the URI. The // resulting ArchiveRequest is suitable for being passed to ArchiveRepository() // if it's determined that the request still needs to be satisfied. @@ -103,7 +118,7 @@ func NewRequest(repoID int64, repo *git.Repository, uri string) (*ArchiveRequest } } } else { - return nil, fmt.Errorf("Unknow ref %s type", r.refName) + return nil, RepoRefNotFoundError{RefName: r.refName} } return r, nil @@ -115,6 +130,49 @@ func (aReq *ArchiveRequest) GetArchiveName() string { return strings.ReplaceAll(aReq.refName, "/", "-") + "." + aReq.Type.String() } +// Await awaits the completion of an ArchiveRequest. If the archive has +// already been prepared the method returns immediately. Otherwise an archiver +// process will be started and its completion awaited. On success the returned +// RepoArchiver may be used to download the archive. Note that even if the +// context is cancelled/times out a started archiver will still continue to run +// in the background. +func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver, error) { + archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID) + if err != nil { + return nil, fmt.Errorf("models.GetRepoArchiver: %v", err) + } + + if archiver != nil && archiver.Status == repo_model.ArchiverReady { + // Archive already generated, we're done. + return archiver, nil + } + + if err := StartArchive(aReq); err != nil { + return nil, fmt.Errorf("archiver.StartArchive: %v", err) + } + + poll := time.NewTicker(time.Second * 1) + defer poll.Stop() + + for { + select { + case <-graceful.GetManager().HammerContext().Done(): + // System stopped. + return nil, graceful.GetManager().HammerContext().Err() + case <-ctx.Done(): + return nil, ctx.Err() + case <-poll.C: + archiver, err = repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID) + if err != nil { + return nil, fmt.Errorf("repo_model.GetRepoArchiver: %v", err) + } + if archiver != nil && archiver.Status == repo_model.ArchiverReady { + return archiver, nil + } + } + } +} + func doArchive(r *ArchiveRequest) (*repo_model.RepoArchiver, error) { txCtx, committer, err := db.TxContext() if err != nil { @@ -147,11 +205,7 @@ func doArchive(r *ArchiveRequest) (*repo_model.RepoArchiver, error) { } } - rPath, err := archiver.RelativePath() - if err != nil { - return nil, err - } - + rPath := archiver.RelativePath() _, err = storage.RepoArchives.Stat(rPath) if err == nil { if archiver.Status == repo_model.ArchiverGenerating { @@ -284,13 +338,10 @@ func StartArchive(request *ArchiveRequest) error { } func deleteOldRepoArchiver(ctx context.Context, archiver *repo_model.RepoArchiver) error { - p, err := archiver.RelativePath() - if err != nil { - return err - } if err := repo_model.DeleteRepoArchiver(ctx, archiver); err != nil { return err } + p := archiver.RelativePath() if err := storage.RepoArchives.Delete(p); err != nil { log.Error("delete repo archive file failed: %v", err) } diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go index ffc1f4efe..327a2e121 100644 --- a/services/repository/files/upload.go +++ b/services/repository/files/upload.go @@ -11,7 +11,6 @@ import ( "path" "strings" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -32,7 +31,7 @@ type UploadRepoFileOptions struct { } type uploadInfo struct { - upload *models.Upload + upload *repo_model.Upload lfsMetaObject *git_model.LFSMetaObject } @@ -56,7 +55,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use return nil } - uploads, err := models.GetUploadsByUUIDs(opts.Files) + uploads, err := repo_model.GetUploadsByUUIDs(opts.Files) if err != nil { return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err) } @@ -157,7 +156,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use return err } - return models.DeleteUploads(uploads...) + return repo_model.DeleteUploads(uploads...) } func copyUploadedLFSFileIntoRepository(info *uploadInfo, filename2attribute2info map[string]map[string]string, t *TemporaryUploadRepository, treePath string) error { diff --git a/services/repository/fork.go b/services/repository/fork.go index b274585ed..96c391e71 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" @@ -23,6 +22,23 @@ import ( "code.gitea.io/gitea/modules/util" ) +// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error. +type ErrForkAlreadyExist struct { + Uname string + RepoName string + ForkName string +} + +// IsErrForkAlreadyExist checks if an error is an ErrForkAlreadyExist. +func IsErrForkAlreadyExist(err error) bool { + _, ok := err.(ErrForkAlreadyExist) + return ok +} + +func (err ErrForkAlreadyExist) Error() string { + return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName) +} + // ForkRepoOptions contains the fork repository options type ForkRepoOptions struct { BaseRepo *repo_model.Repository @@ -37,7 +53,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork return nil, err } if forkedRepo != nil { - return nil, models.ErrForkAlreadyExist{ + return nil, ErrForkAlreadyExist{ Uname: owner.Name, RepoName: opts.BaseRepo.FullName(), ForkName: forkedRepo.FullName(), @@ -93,7 +109,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork }() err = db.WithTx(func(txCtx context.Context) error { - if err = models.CreateRepository(txCtx, doer, owner, repo, false); err != nil { + if err = repo_module.CreateRepositoryByExample(txCtx, doer, owner, repo, false); err != nil { return err } diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go index 376c5c06d..d4ba50735 100644 --- a/services/repository/fork_test.go +++ b/services/repository/fork_test.go @@ -7,7 +7,6 @@ package repository import ( "testing" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -30,5 +29,5 @@ func TestForkRepository(t *testing.T) { }) assert.Nil(t, fork) assert.Error(t, err) - assert.True(t, models.IsErrForkAlreadyExist(err)) + assert.True(t, IsErrForkAlreadyExist(err)) } diff --git a/services/repository/push.go b/services/repository/push.go index 65ac7b660..f3f505aa0 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" @@ -292,7 +291,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { // PushUpdateAddDeleteTags updates a number of added and delete tags func PushUpdateAddDeleteTags(repo *repo_model.Repository, gitRepo *git.Repository, addTags, delTags []string) error { return db.WithTx(func(ctx context.Context) error { - if err := models.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil { + if err := repo_model.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil { return err } return pushUpdateAddTags(ctx, repo, gitRepo, addTags) @@ -310,16 +309,16 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo lowerTags = append(lowerTags, strings.ToLower(tag)) } - releases, err := models.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags) + releases, err := repo_model.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags) if err != nil { return fmt.Errorf("GetReleasesByRepoIDAndNames: %v", err) } - relMap := make(map[string]*models.Release) + relMap := make(map[string]*repo_model.Release) for _, rel := range releases { relMap[rel.LowerTagName] = rel } - newReleases := make([]*models.Release, 0, len(lowerTags)-len(relMap)) + newReleases := make([]*repo_model.Release, 0, len(lowerTags)-len(relMap)) emailToUser := make(map[string]*user_model.User) @@ -366,7 +365,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo rel, has := relMap[lowerTag] if !has { - rel = &models.Release{ + rel = &repo_model.Release{ RepoID: repo.ID, Title: "", TagName: tags[i], @@ -393,7 +392,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo if rel.IsTag && author != nil { rel.PublisherID = author.ID } - if err = models.UpdateRelease(ctx, rel); err != nil { + if err = repo_model.UpdateRelease(ctx, rel); err != nil { return fmt.Errorf("Update: %v", err) } } diff --git a/services/repository/repository.go b/services/repository/repository.go index 4bde6879a..d53035836 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -25,7 +25,7 @@ import ( ) // CreateRepository creates a repository for the user/organization. -func CreateRepository(doer, owner *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { +func CreateRepository(doer, owner *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) { repo, err := repo_module.CreateRepository(doer, owner, opts) if err != nil { // No need to rollback here we should do this in CreateRepository... @@ -69,7 +69,7 @@ func PushCreateRepo(authUser, owner *user_model.User, repoName string) (*repo_mo } } - repo, err := CreateRepository(authUser, owner, models.CreateRepoOptions{ + repo, err := CreateRepository(authUser, owner, repo_module.CreateRepoOptions{ Name: repoName, IsPrivate: setting.Repository.DefaultPushCreatePrivate, }) @@ -117,7 +117,7 @@ func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Ty } return repo, unitType, err } else if a.ReleaseID != 0 { - rel, err := models.GetReleaseByID(db.DefaultContext, a.ReleaseID) + rel, err := repo_model.GetReleaseByID(db.DefaultContext, a.ReleaseID) if err != nil { return nil, unit.TypeReleases, err } diff --git a/services/repository/transfer.go b/services/repository/transfer.go index ae1538324..a0f4a7685 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -16,6 +16,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/sync" ) @@ -49,7 +50,7 @@ func TransferOwnership(doer, newOwner *user_model.User, repo *repo_model.Reposit } for _, team := range teams { - if err := models.AddRepository(team, newRepo); err != nil { + if err := models.AddRepository(db.DefaultContext, team, newRepo); err != nil { return err } } @@ -111,7 +112,7 @@ func StartRepositoryTransfer(doer, newOwner *user_model.User, repo *repo_model.R return err } if !hasAccess { - if err := models.AddCollaborator(repo, newOwner); err != nil { + if err := repo_module.AddCollaborator(repo, newOwner); err != nil { return err } if err := repo_model.ChangeCollaborationAccessMode(repo, newOwner.ID, perm.AccessModeRead); err != nil { diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go index 3c929f2f7..bf2a0ce0a 100644 --- a/services/repository/transfer_test.go +++ b/services/repository/transfer_test.go @@ -8,7 +8,7 @@ import ( "sync" "testing" - "code.gitea.io/gitea/models" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" @@ -49,8 +49,8 @@ func TestTransferOwnership(t *testing.T) { exist, err = util.IsExist(repo_model.RepoPath("user2", "repo3")) assert.NoError(t, err) assert.True(t, exist) - unittest.AssertExistsAndLoadBean(t, &models.Action{ - OpType: models.ActionTransferRepo, + unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ + OpType: activities_model.ActionTransferRepo, ActUserID: 2, RepoID: 3, Content: "user3/repo3", diff --git a/services/task/migrate.go b/services/task/migrate.go index 651681ef6..775cbf612 100644 --- a/services/task/migrate.go +++ b/services/task/migrate.go @@ -10,6 +10,7 @@ import ( "strings" "code.gitea.io/gitea/models" + admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -40,7 +41,7 @@ func handleCreateError(owner *user_model.User, err error) error { } } -func runMigrateTask(t *models.Task) (err error) { +func runMigrateTask(t *admin_model.Task) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("PANIC whilst trying to do migrate task: %v", e) @@ -48,7 +49,7 @@ func runMigrateTask(t *models.Task) (err error) { } if err == nil { - err = models.FinishMigrateTask(t) + err = admin_model.FinishMigrateTask(t) if err == nil { notification.NotifyMigrateRepository(t.Doer, t.Owner, t.Repo) return @@ -110,7 +111,7 @@ func runMigrateTask(t *models.Task) (err error) { } t.Repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...interface{}) { - message := models.TranslatableMessage{ + message := admin_model.TranslatableMessage{ Format: format, Args: args, } diff --git a/services/task/task.go b/services/task/task.go index 9deb0286c..138dc88a0 100644 --- a/services/task/task.go +++ b/services/task/task.go @@ -7,7 +7,7 @@ package task import ( "fmt" - "code.gitea.io/gitea/models" + admin_model "code.gitea.io/gitea/models/admin" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -27,7 +27,7 @@ import ( var taskQueue queue.Queue // Run a task -func Run(t *models.Task) error { +func Run(t *admin_model.Task) error { switch t.Type { case structs.TaskTypeMigrateRepo: return runMigrateTask(t) @@ -38,7 +38,7 @@ func Run(t *models.Task) error { // Init will start the service to get all unfinished tasks and run them func Init() error { - taskQueue = queue.CreateQueue("task", handle, &models.Task{}) + taskQueue = queue.CreateQueue("task", handle, &admin_model.Task{}) if taskQueue == nil { return fmt.Errorf("Unable to create Task Queue") @@ -51,7 +51,7 @@ func Init() error { func handle(data ...queue.Data) []queue.Data { for _, datum := range data { - task := datum.(*models.Task) + task := datum.(*admin_model.Task) if err := Run(task); err != nil { log.Error("Run task failed: %v", err) } @@ -70,7 +70,7 @@ func MigrateRepository(doer, u *user_model.User, opts base.MigrateOptions) error } // CreateMigrateTask creates a migrate task -func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*models.Task, error) { +func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*admin_model.Task, error) { // encrypt credentials for persistence var err error opts.CloneAddrEncrypted, err = secret.EncryptSecret(setting.SecretKey, opts.CloneAddr) @@ -93,7 +93,7 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*mod return nil, err } - task := &models.Task{ + task := &admin_model.Task{ DoerID: doer.ID, OwnerID: u.ID, Type: structs.TaskTypeMigrateRepo, @@ -101,11 +101,11 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*mod PayloadContent: string(bs), } - if err := models.CreateTask(task); err != nil { + if err := admin_model.CreateTask(task); err != nil { return nil, err } - repo, err := repo_module.CreateRepository(doer, u, models.CreateRepoOptions{ + repo, err := repo_module.CreateRepository(doer, u, repo_module.CreateRepoOptions{ Name: opts.RepoName, Description: opts.Description, OriginalURL: opts.OriginalURL, diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 642cf6f2f..5112bdb34 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -15,7 +15,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" - dingtalk "github.com/lunny/dingtalk_webhook" + dingtalk "gitea.com/lunny/dingtalk_webhook" ) type ( @@ -107,6 +107,14 @@ func (d *DingtalkPayload) Issue(p *api.IssuePayload) (api.Payloader, error) { return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+attachmentText, "view issue", p.Issue.HTMLURL), nil } +// Wiki implements PayloadConvertor Wiki method +func (d *DingtalkPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true) + url := p.Repository.HTMLURL + "/wiki/" + url.PathEscape(p.Page) + + return createDingtalkPayload(text, text, "view wiki", url), nil +} + // IssueComment implements PayloadConvertor IssueComment method func (d *DingtalkPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) { text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true) diff --git a/services/webhook/dingtalk_test.go b/services/webhook/dingtalk_test.go index b66b5e43a..efc9601c1 100644 --- a/services/webhook/dingtalk_test.go +++ b/services/webhook/dingtalk_test.go @@ -189,6 +189,44 @@ func TestDingTalkPayload(t *testing.T) { assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL)) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(DingtalkPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DingtalkPayload{}, pl) + + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Text) + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Title) + assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL)) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DingtalkPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Text) + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Title) + assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL)) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DingtalkPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*DingtalkPayload).ActionCard.Text) + assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*DingtalkPayload).ActionCard.Title) + assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL)) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/discord.go b/services/webhook/discord.go index ae5460b9a..7b6f0f0b1 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -7,6 +7,7 @@ package webhook import ( "errors" "fmt" + "net/url" "strconv" "strings" @@ -235,6 +236,19 @@ func (d *DiscordPayload) Repository(p *api.RepositoryPayload) (api.Payloader, er return d.createPayload(p.Sender, title, "", url, color), nil } +// Wiki implements PayloadConvertor Wiki method +func (d *DiscordPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, color, _ := getWikiPayloadInfo(p, noneLinkFormatter, false) + htmlLink := p.Repository.HTMLURL + "/wiki/" + url.PathEscape(p.Page) + + var description string + if p.Action != api.HookWikiDeleted { + description = p.Comment + } + + return d.createPayload(p.Sender, text, description, htmlLink, color), nil +} + // Release implements PayloadConvertor Release method func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { text, color := getReleasePayloadInfo(p, noneLinkFormatter, false) diff --git a/services/webhook/discord_test.go b/services/webhook/discord_test.go index 8fe20c010..8e4e60a7f 100644 --- a/services/webhook/discord_test.go +++ b/services/webhook/discord_test.go @@ -212,6 +212,53 @@ func TestDiscordPayload(t *testing.T) { assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(DiscordPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DiscordPayload{}, pl) + + assert.Len(t, pl.(*DiscordPayload).Embeds, 1) + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*DiscordPayload).Embeds[0].Title) + assert.Equal(t, "Wiki change comment", pl.(*DiscordPayload).Embeds[0].Description) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL) + assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name) + assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL) + assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DiscordPayload{}, pl) + + assert.Len(t, pl.(*DiscordPayload).Embeds, 1) + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*DiscordPayload).Embeds[0].Title) + assert.Equal(t, "Wiki change comment", pl.(*DiscordPayload).Embeds[0].Description) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL) + assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name) + assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL) + assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &DiscordPayload{}, pl) + + assert.Len(t, pl.(*DiscordPayload).Embeds, 1) + assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*DiscordPayload).Embeds[0].Title) + assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL) + assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name) + assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL) + assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 5b20c7dda..782684d0f 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -145,6 +145,13 @@ func (f *FeishuPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err return nil, nil } +// Wiki implements PayloadConvertor Wiki method +func (f *FeishuPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true) + + return newFeishuTextPayload(text), nil +} + // Release implements PayloadConvertor Release method func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true) diff --git a/services/webhook/feishu_test.go b/services/webhook/feishu_test.go index d862b015e..85cfb759f 100644 --- a/services/webhook/feishu_test.go +++ b/services/webhook/feishu_test.go @@ -145,6 +145,35 @@ func TestFeishuPayload(t *testing.T) { assert.Equal(t, "[test/repo] Repository created", pl.(*FeishuPayload).Content.Text) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(FeishuPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &FeishuPayload{}, pl) + + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*FeishuPayload).Content.Text) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &FeishuPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*FeishuPayload).Content.Text) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &FeishuPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*FeishuPayload).Content.Text) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/general.go b/services/webhook/general.go index e8006faba..5be177d33 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -161,6 +161,35 @@ func getReleasePayloadInfo(p *api.ReleasePayload, linkFormatter linkFormatter, w return text, color } +func getWikiPayloadInfo(p *api.WikiPayload, linkFormatter linkFormatter, withSender bool) (string, int, string) { + repoLink := linkFormatter(p.Repository.HTMLURL, p.Repository.FullName) + pageLink := linkFormatter(p.Repository.HTMLURL+"/wiki/"+url.PathEscape(p.Page), p.Page) + + var text string + color := greenColor + + switch p.Action { + case api.HookWikiCreated: + text = fmt.Sprintf("[%s] New wiki page '%s'", repoLink, pageLink) + case api.HookWikiEdited: + text = fmt.Sprintf("[%s] Wiki page '%s' edited", repoLink, pageLink) + color = yellowColor + case api.HookWikiDeleted: + text = fmt.Sprintf("[%s] Wiki page '%s' deleted", repoLink, pageLink) + color = redColor + } + + if p.Action != api.HookWikiDeleted && p.Comment != "" { + text += fmt.Sprintf(" (%s)", p.Comment) + } + + if withSender { + text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + } + + return text, color, pageLink +} + func getIssueCommentPayloadInfo(p *api.IssueCommentPayload, linkFormatter linkFormatter, withSender bool) (string, string, int) { repoLink := linkFormatter(p.Repository.HTMLURL, p.Repository.FullName) issueTitle := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title) diff --git a/services/webhook/general_test.go b/services/webhook/general_test.go index 4d73afe06..4acf51ac7 100644 --- a/services/webhook/general_test.go +++ b/services/webhook/general_test.go @@ -195,6 +195,22 @@ func pullRequestCommentTestPayload() *api.IssueCommentPayload { } } +func wikiTestPayload() *api.WikiPayload { + return &api.WikiPayload{ + Repository: &api.Repository{ + HTMLURL: "http://localhost:3000/test/repo", + Name: "repo", + FullName: "test/repo", + }, + Sender: &api.User{ + UserName: "user1", + AvatarURL: "http://localhost:3000/user1/avatar", + }, + Page: "index", + Comment: "Wiki change comment", + } +} + func pullReleaseTestPayload() *api.ReleasePayload { return &api.ReleasePayload{ Action: api.HookReleasePublished, @@ -469,6 +485,44 @@ func TestGetPullRequestPayloadInfo(t *testing.T) { } } +func TestGetWikiPayloadInfo(t *testing.T) { + p := wikiTestPayload() + + cases := []struct { + action api.HookWikiAction + text string + color int + link string + }{ + { + api.HookWikiCreated, + "[test/repo] New wiki page 'index' (Wiki change comment) by user1", + greenColor, + "index", + }, + { + api.HookWikiEdited, + "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", + yellowColor, + "index", + }, + { + api.HookWikiDeleted, + "[test/repo] Wiki page 'index' deleted by user1", + redColor, + "index", + }, + } + + for i, c := range cases { + p.Action = c.action + text, color, link := getWikiPayloadInfo(p, noneLinkFormatter, true) + assert.Equal(t, c.text, text, "case %d", i) + assert.Equal(t, c.color, color, "case %d", i) + assert.Equal(t, c.link, link, "case %d", i) + } +} + func TestGetReleasePayloadInfo(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index a42ab2a93..f4c4cf0e9 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -143,6 +143,13 @@ func (m *MatrixPayloadUnsafe) IssueComment(p *api.IssueCommentPayload) (api.Payl return getMatrixPayloadUnsafe(text, nil, m.AccessToken, m.MsgType), nil } +// Wiki implements PayloadConvertor Wiki method +func (m *MatrixPayloadUnsafe) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, MatrixLinkFormatter, true) + + return getMatrixPayloadUnsafe(text, nil, m.AccessToken, m.MsgType), nil +} + // Release implements PayloadConvertor Release method func (m *MatrixPayloadUnsafe) Release(p *api.ReleasePayload) (api.Payloader, error) { text, _ := getReleasePayloadInfo(p, MatrixLinkFormatter, true) diff --git a/services/webhook/matrix_test.go b/services/webhook/matrix_test.go index 34196aedf..4cab84533 100644 --- a/services/webhook/matrix_test.go +++ b/services/webhook/matrix_test.go @@ -156,6 +156,38 @@ func TestMatrixPayload(t *testing.T) { assert.Equal(t, `[test/repo] Repository created by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(MatrixPayloadUnsafe) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MatrixPayloadUnsafe{}, pl) + + assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New wiki page '[index](http://localhost:3000/test/repo/wiki/index)' (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayloadUnsafe).Body) + assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MatrixPayloadUnsafe{}, pl) + + assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' edited (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayloadUnsafe).Body) + assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MatrixPayloadUnsafe{}, pl) + + assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' deleted by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayloadUnsafe).Body) + assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index 59e2e9349..140600478 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -6,6 +6,7 @@ package webhook import ( "fmt" + "net/url" "strings" webhook_model "code.gitea.io/gitea/models/webhook" @@ -266,6 +267,21 @@ func (m *MSTeamsPayload) Repository(p *api.RepositoryPayload) (api.Payloader, er ), nil } +// Wiki implements PayloadConvertor Wiki method +func (m *MSTeamsPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + title, color, _ := getWikiPayloadInfo(p, noneLinkFormatter, false) + + return createMSTeamsPayload( + p.Repository, + p.Sender, + title, + "", + p.Repository.HTMLURL+"/wiki/"+url.PathEscape(p.Page), + color, + &MSTeamsFact{"Repository:", p.Repository.FullName}, + ), nil +} + // Release implements PayloadConvertor Release method func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { title, color := getReleasePayloadInfo(p, noneLinkFormatter, false) diff --git a/services/webhook/msteams_test.go b/services/webhook/msteams_test.go index 3fdf47c1a..8292beed7 100644 --- a/services/webhook/msteams_test.go +++ b/services/webhook/msteams_test.go @@ -330,6 +330,80 @@ func TestMSTeamsPayload(t *testing.T) { assert.Equal(t, "http://localhost:3000/test/repo", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(MSTeamsPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MSTeamsPayload{}, pl) + + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*MSTeamsPayload).Title) + assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*MSTeamsPayload).Summary) + assert.Len(t, pl.(*MSTeamsPayload).Sections, 1) + assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle) + assert.Equal(t, "", pl.(*MSTeamsPayload).Sections[0].Text) + assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2) + for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts { + if fact.Name == "Repository:" { + assert.Equal(t, p.Repository.FullName, fact.Value) + } else { + t.Fail() + } + } + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1) + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MSTeamsPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*MSTeamsPayload).Title) + assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*MSTeamsPayload).Summary) + assert.Len(t, pl.(*MSTeamsPayload).Sections, 1) + assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle) + assert.Equal(t, "", pl.(*MSTeamsPayload).Sections[0].Text) + assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2) + for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts { + if fact.Name == "Repository:" { + assert.Equal(t, p.Repository.FullName, fact.Value) + } else { + t.Fail() + } + } + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1) + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &MSTeamsPayload{}, pl) + + assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*MSTeamsPayload).Title) + assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*MSTeamsPayload).Summary) + assert.Len(t, pl.(*MSTeamsPayload).Sections, 1) + assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle) + assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text) + assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2) + for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts { + if fact.Name == "Repository:" { + assert.Equal(t, p.Repository.FullName, fact.Value) + } else { + t.Fail() + } + } + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1) + assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1) + assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index ace93b13f..5badc7462 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -94,6 +94,11 @@ func (f *PackagistPayload) Repository(p *api.RepositoryPayload) (api.Payloader, return nil, nil } +// Wiki implements PayloadConvertor Wiki method +func (f *PackagistPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + return nil, nil +} + // Release implements PayloadConvertor Release method func (f *PackagistPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return nil, nil diff --git a/services/webhook/packagist_test.go b/services/webhook/packagist_test.go index 08912924d..4a24b7652 100644 --- a/services/webhook/packagist_test.go +++ b/services/webhook/packagist_test.go @@ -116,6 +116,26 @@ func TestPackagistPayload(t *testing.T) { require.Nil(t, pl) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(PackagistPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.Nil(t, pl) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.Nil(t, pl) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.Nil(t, pl) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/payloader.go b/services/webhook/payloader.go index 0e09dd1b1..a9d01c989 100644 --- a/services/webhook/payloader.go +++ b/services/webhook/payloader.go @@ -22,6 +22,7 @@ type PayloadConvertor interface { Review(*api.PullRequestPayload, webhook_model.HookEventType) (api.Payloader, error) Repository(*api.RepositoryPayload) (api.Payloader, error) Release(*api.ReleasePayload) (api.Payloader, error) + Wiki(*api.WikiPayload) (api.Payloader, error) } func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_model.HookEventType) (api.Payloader, error) { @@ -51,6 +52,8 @@ func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_model.H return s.Repository(p.(*api.RepositoryPayload)) case webhook_model.HookEventRelease: return s.Release(p.(*api.ReleasePayload)) + case webhook_model.HookEventWiki: + return s.Wiki(p.(*api.WikiPayload)) } return s, nil } diff --git a/services/webhook/slack.go b/services/webhook/slack.go index e3d0d406d..63cc6f8ca 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -157,6 +157,13 @@ func (s *SlackPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, }}), nil } +// Wiki implements PayloadConvertor Wiki method +func (s *SlackPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, SlackLinkFormatter, true) + + return s.createPayload(text, nil), nil +} + // Release implements PayloadConvertor Release method func (s *SlackPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { text, _ := getReleasePayloadInfo(p, SlackLinkFormatter, true) diff --git a/services/webhook/slack_test.go b/services/webhook/slack_test.go index 0f08785d2..3af38b515 100644 --- a/services/webhook/slack_test.go +++ b/services/webhook/slack_test.go @@ -145,6 +145,35 @@ func TestSlackPayload(t *testing.T) { assert.Equal(t, "[] Repository created by ", pl.(*SlackPayload).Text) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(SlackPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &SlackPayload{}, pl) + + assert.Equal(t, "[] New wiki page '' (Wiki change comment) by ", pl.(*SlackPayload).Text) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &SlackPayload{}, pl) + + assert.Equal(t, "[] Wiki page '' edited (Wiki change comment) by ", pl.(*SlackPayload).Text) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &SlackPayload{}, pl) + + assert.Equal(t, "[] Wiki page '' deleted by ", pl.(*SlackPayload).Text) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index 64211493e..13471d864 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -171,6 +171,13 @@ func (t *TelegramPayload) Repository(p *api.RepositoryPayload) (api.Payloader, e return nil, nil } +// Wiki implements PayloadConvertor Wiki method +func (t *TelegramPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, htmlLinkFormatter, true) + + return createTelegramPayload(text), nil +} + // Release implements PayloadConvertor Release method func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { text, _ := getReleasePayloadInfo(p, htmlLinkFormatter, true) diff --git a/services/webhook/telegram_test.go b/services/webhook/telegram_test.go index 2f8309016..5ca78d050 100644 --- a/services/webhook/telegram_test.go +++ b/services/webhook/telegram_test.go @@ -145,6 +145,35 @@ func TestTelegramPayload(t *testing.T) { assert.Equal(t, `[test/repo] Repository created`, pl.(*TelegramPayload).Message) }) + t.Run("Wiki", func(t *testing.T) { + p := wikiTestPayload() + + d := new(TelegramPayload) + p.Action = api.HookWikiCreated + pl, err := d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &TelegramPayload{}, pl) + + assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.(*TelegramPayload).Message) + + p.Action = api.HookWikiEdited + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &TelegramPayload{}, pl) + + assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.(*TelegramPayload).Message) + + p.Action = api.HookWikiDeleted + pl, err = d.Wiki(p) + require.NoError(t, err) + require.NotNil(t, pl) + require.IsType(t, &TelegramPayload{}, pl) + + assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.(*TelegramPayload).Message) + }) + t.Run("Release", func(t *testing.T) { p := pullReleaseTestPayload() diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index de8b77706..bd4c3e085 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -166,6 +166,13 @@ func (f *WechatworkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, return nil, nil } +// Wiki implements PayloadConvertor Wiki method +func (f *WechatworkPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { + text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true) + + return newWechatworkMarkdownPayload(text), nil +} + // Release implements PayloadConvertor Release method func (f *WechatworkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true) diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 43e35eed6..b341b048c 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -12,7 +12,6 @@ import ( "os" "strings" - "code.gitea.io/gitea/models" admin_model "code.gitea.io/gitea/models/admin" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -33,7 +32,7 @@ var ( func nameAllowed(name string) error { if util.IsStringInSlice(name, reservedWikiNames) { - return models.ErrWikiReservedName{ + return repo_model.ErrWikiReservedName{ Title: name, } } @@ -59,7 +58,7 @@ func NameToFilename(name string) string { // FilenameToName converts a wiki filename to its corresponding page name. func FilenameToName(filename string) (string, error) { if !strings.HasSuffix(filename, ".md") { - return "", models.ErrWikiInvalidFileName{ + return "", repo_model.ErrWikiInvalidFileName{ FileName: filename, } } @@ -119,7 +118,7 @@ func prepareWikiFileName(gitRepo *git.Repository, wikiName string) (bool, string return foundEscaped, escaped, nil } -// updateWikiPage adds a new page to the repository wiki. +// updateWikiPage adds a new page or edits an existing page in repository wiki. func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldWikiName, newWikiName, content, message string, isNew bool) (err error) { if err = nameAllowed(newWikiName); err != nil { return err @@ -178,7 +177,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model if isNew { if isWikiExist { - return models.ErrWikiAlreadyExist{ + return repo_model.ErrWikiAlreadyExist{ Title: newWikiPath, } } diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 1852ddbcb..cabeecb60 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -5,16 +5,13 @@ package wiki import ( - "os" "path/filepath" "testing" - "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) @@ -90,11 +87,11 @@ func TestWikiFilenameToName(t *testing.T) { } { _, err := FilenameToName(badFilename) assert.Error(t, err) - assert.True(t, models.IsErrWikiInvalidFileName(err)) + assert.True(t, repo_model.IsErrWikiInvalidFileName(err)) } _, err := FilenameToName("badescaping%%.md") assert.Error(t, err) - assert.False(t, models.IsErrWikiInvalidFileName(err)) + assert.False(t, repo_model.IsErrWikiInvalidFileName(err)) } func TestWikiNameToFilenameToName(t *testing.T) { @@ -157,7 +154,7 @@ func TestRepository_AddWikiPage(t *testing.T) { // test for already-existing wiki name err := AddWikiPage(git.DefaultContext, doer, repo, "Home", wikiContent, commitMsg) assert.Error(t, err) - assert.True(t, models.IsErrWikiAlreadyExist(err)) + assert.True(t, repo_model.IsErrWikiAlreadyExist(err)) }) t.Run("check wiki reserved name", func(t *testing.T) { @@ -165,7 +162,7 @@ func TestRepository_AddWikiPage(t *testing.T) { // test for reserved wiki name err := AddWikiPage(git.DefaultContext, doer, repo, "_edit", wikiContent, commitMsg) assert.Error(t, err) - assert.True(t, models.IsErrWikiReservedName(err)) + assert.True(t, repo_model.IsErrWikiReservedName(err)) }) } @@ -274,15 +271,9 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { unittest.PrepareTestEnv(t) // Now create a temporaryDirectory - tmpDir, err := os.MkdirTemp("", "empty-wiki") - assert.NoError(t, err) - defer func() { - if _, err := os.Stat(tmpDir); !os.IsNotExist(err) { - _ = util.RemoveAll(tmpDir) - } - }() + tmpDir := t.TempDir() - err = git.InitRepository(git.DefaultContext, tmpDir, true) + err := git.InitRepository(git.DefaultContext, tmpDir, true) assert.NoError(t, err) gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir) diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index af3f381c8..bf9d53152 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -23,7 +23,7 @@ {{if or .Source.IsLDAP .Source.IsDLDAP}} - {{ $cfg:=.Source.Cfg }} + {{$cfg:=.Source.Cfg}}